miniupnpc: update getDevicesFromMiniSSDPD() to process longer minissdpd responses
This commit is contained in:
parent
edd7c7bbdc
commit
27e2aa3841
|
@ -1,6 +1,10 @@
|
|||
$Id: Changelog.txt,v 1.206 2015/05/22 10:23:47 nanard Exp $
|
||||
miniUPnP client Changelog.
|
||||
|
||||
2015/06/16:
|
||||
update getDevicesFromMiniSSDPD() to process longer minissdpd
|
||||
responses
|
||||
|
||||
2015/05/22:
|
||||
add searchalltypes param to upnpDiscoverDevices()
|
||||
increments API_VERSION to 13
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $Id: codelength.h,v 1.3 2011/07/30 13:10:05 nanard Exp $ */
|
||||
/* Project : miniupnp
|
||||
* Author : Thomas BERNARD
|
||||
* copyright (c) 2005-2011 Thomas Bernard
|
||||
* copyright (c) 2005-2015 Thomas Bernard
|
||||
* This software is subjet to the conditions detailed in the
|
||||
* provided LICENCE file. */
|
||||
#ifndef CODELENGTH_H_INCLUDED
|
||||
|
@ -10,10 +10,30 @@
|
|||
/* Encode length by using 7bit per Byte :
|
||||
* Most significant bit of each byte specifies that the
|
||||
* following byte is part of the code */
|
||||
|
||||
/* n : unsigned
|
||||
* p : unsigned char *
|
||||
*/
|
||||
#define DECODELENGTH(n, p) n = 0; \
|
||||
do { n = (n << 7) | (*p & 0x7f); } \
|
||||
while((*(p++)&0x80) && (n<(1<<25)));
|
||||
|
||||
/* n : unsigned
|
||||
* READ : function/macro to read one byte (unsigned char)
|
||||
*/
|
||||
#define DECODELENGTH_READ(n, READ) \
|
||||
n = 0; \
|
||||
do { \
|
||||
unsigned char c; \
|
||||
READ(c); \
|
||||
n = (n << 7) | (c & 0x07f); \
|
||||
if(!(c&0x80)) break; \
|
||||
} while(n<(1<<25));
|
||||
|
||||
/* n : unsigned
|
||||
* p : unsigned char *
|
||||
* p_limit : unsigned char *
|
||||
*/
|
||||
#define DECODELENGTH_CHECKLIMIT(n, p, p_limit) \
|
||||
n = 0; \
|
||||
do { \
|
||||
|
@ -21,11 +41,14 @@
|
|||
n = (n << 7) | (*(p) & 0x7f); \
|
||||
} while((*((p)++)&0x80) && (n<(1<<25)));
|
||||
|
||||
|
||||
/* n : unsigned
|
||||
* p : unsigned char *
|
||||
*/
|
||||
#define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \
|
||||
if(n>=2097152) *(p++) = (n >> 21) | 0x80; \
|
||||
if(n>=16384) *(p++) = (n >> 14) | 0x80; \
|
||||
if(n>=128) *(p++) = (n >> 7) | 0x80; \
|
||||
*(p++) = n & 0x7f;
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* CODELENGTH_H_INCLUDED */
|
||||
|
|
|
@ -46,14 +46,59 @@ getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
|
|||
{
|
||||
struct UPNPDev * tmp;
|
||||
struct UPNPDev * devlist = NULL;
|
||||
unsigned char buffer[4*1024]; /* is that enough ? */
|
||||
unsigned char buffer[256];
|
||||
ssize_t n;
|
||||
unsigned char * p;
|
||||
unsigned char * url;
|
||||
unsigned int bufferindex;
|
||||
unsigned int i, ndev;
|
||||
unsigned int urlsize, stsize, usnsize, l;
|
||||
int s;
|
||||
struct sockaddr_un addr;
|
||||
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
|
||||
struct timeval timeout;
|
||||
#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
|
||||
|
||||
/* macros used to read from unix socket */
|
||||
#define READ_BYTE_BUFFER(c) \
|
||||
if(bufferindex >= n) { \
|
||||
n = read(s, buffer, sizeof(buffer)); \
|
||||
if(n<=0) break; \
|
||||
bufferindex = 0; \
|
||||
} \
|
||||
c = buffer[bufferindex++];
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif /* MIN */
|
||||
|
||||
#define READ_COPY_BUFFER(dst, len) \
|
||||
for(l = len, p = (unsigned char *)dst; l > 0; ) { \
|
||||
unsigned int lcopy; \
|
||||
if(bufferindex >= n) { \
|
||||
n = read(s, buffer, sizeof(buffer)); \
|
||||
if(n<=0) break; \
|
||||
bufferindex = 0; \
|
||||
} \
|
||||
lcopy = MIN(l, (n - bufferindex)); \
|
||||
memcpy(p, buffer + bufferindex, lcopy); \
|
||||
l -= lcopy; \
|
||||
p += lcopy; \
|
||||
bufferindex += lcopy; \
|
||||
}
|
||||
|
||||
#define READ_DISCARD_BUFFER(len) \
|
||||
for(l = len; l > 0; ) { \
|
||||
unsigned int lcopy; \
|
||||
if(bufferindex >= n) { \
|
||||
n = read(s, buffer, sizeof(buffer)); \
|
||||
if(n<=0) break; \
|
||||
bufferindex = 0; \
|
||||
} \
|
||||
lcopy = MIN(l, (n - bufferindex)); \
|
||||
l -= lcopy; \
|
||||
bufferindex += lcopy; \
|
||||
}
|
||||
|
||||
s = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if(s < 0)
|
||||
|
@ -62,6 +107,21 @@ getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
|
|||
perror("socket(unix)");
|
||||
return NULL;
|
||||
}
|
||||
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
|
||||
/* setting a 3 seconds timeout */
|
||||
timeout.tv_sec = 3;
|
||||
timeout.tv_usec = 0;
|
||||
if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
|
||||
{
|
||||
perror("setsockopt");
|
||||
}
|
||||
timeout.tv_sec = 3;
|
||||
timeout.tv_usec = 0;
|
||||
if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
|
||||
{
|
||||
perror("setsockopt");
|
||||
}
|
||||
#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path));
|
||||
/* TODO : check if we need to handle the EINTR */
|
||||
|
@ -85,6 +145,10 @@ getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
|
|||
if(p + stsize > buffer + sizeof(buffer))
|
||||
{
|
||||
/* devtype is too long ! */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "devtype is too long ! stsize=%u sizeof(buffer)=%u\n",
|
||||
stsize, (unsigned)sizeof(buffer));
|
||||
#endif /* DEBUG */
|
||||
close(s);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -105,36 +169,66 @@ getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
|
|||
return NULL;
|
||||
}
|
||||
ndev = buffer[0];
|
||||
p = buffer + 1;
|
||||
bufferindex = 1;
|
||||
for(i = 0; i < ndev; i++)
|
||||
{
|
||||
if(p+2>=buffer+sizeof(buffer))
|
||||
DECODELENGTH_READ(urlsize, READ_BYTE_BUFFER);
|
||||
if(n<=0) {
|
||||
break;
|
||||
DECODELENGTH(urlsize, p);
|
||||
if(p+urlsize+2>=buffer+sizeof(buffer))
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf(" urlsize=%u", urlsize);
|
||||
#endif /* DEBUG */
|
||||
url = malloc(urlsize);
|
||||
if(url == NULL) {
|
||||
break;
|
||||
url = p;
|
||||
p += urlsize;
|
||||
DECODELENGTH(stsize, p);
|
||||
if(p+stsize+2>=buffer+sizeof(buffer))
|
||||
}
|
||||
READ_COPY_BUFFER(url, urlsize);
|
||||
if(n<=0) {
|
||||
free(url);
|
||||
break;
|
||||
}
|
||||
DECODELENGTH_READ(stsize, READ_BYTE_BUFFER);
|
||||
if(n<=0) {
|
||||
free(url);
|
||||
break;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf(" stsize=%u", stsize);
|
||||
#endif /* DEBUG */
|
||||
tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
|
||||
if(tmp == NULL) {
|
||||
free(url);
|
||||
break;
|
||||
}
|
||||
tmp->pNext = devlist;
|
||||
tmp->descURL = tmp->buffer;
|
||||
tmp->st = tmp->buffer + 1 + urlsize;
|
||||
memcpy(tmp->buffer, url, urlsize);
|
||||
tmp->buffer[urlsize] = '\0';
|
||||
memcpy(tmp->buffer + urlsize + 1, p, stsize);
|
||||
p += stsize;
|
||||
free(url);
|
||||
url = NULL;
|
||||
READ_COPY_BUFFER(tmp->buffer + urlsize + 1, stsize);
|
||||
if(n<=0) {
|
||||
free(tmp);
|
||||
break;
|
||||
}
|
||||
tmp->buffer[urlsize+1+stsize] = '\0';
|
||||
tmp->scope_id = 0; /* default value. scope_id is not available with MiniSSDPd */
|
||||
devlist = tmp;
|
||||
/* added for compatibility with recent versions of MiniSSDPd
|
||||
* >= 2007/12/19 */
|
||||
DECODELENGTH(usnsize, p);
|
||||
p += usnsize;
|
||||
if(p>buffer + sizeof(buffer))
|
||||
DECODELENGTH_READ(usnsize, READ_BYTE_BUFFER);
|
||||
if(n<=0) {
|
||||
break;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf(" usnsize=%u\n", usnsize);
|
||||
#endif /* DEBUG */
|
||||
READ_DISCARD_BUFFER(usnsize);
|
||||
if(n<=0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
close(s);
|
||||
return devlist;
|
||||
|
|
|
@ -63,9 +63,6 @@
|
|||
#include <errno.h>
|
||||
#define closesocket close
|
||||
#endif /* #else _WIN32 */
|
||||
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#if defined(__amigaos__) || defined(__amigaos4__)
|
||||
/* Amiga OS specific stuff */
|
||||
#define TIMEVAL struct timeval
|
||||
|
|
Loading…
Reference in New Issue