diff --git a/upnp/src/genlib/net/sock.c b/upnp/src/genlib/net/sock.c index 21b7274..e145bea 100644 --- a/upnp/src/genlib/net/sock.c +++ b/upnp/src/genlib/net/sock.c @@ -117,7 +117,7 @@ static int sock_read_write( fd_set readSet; fd_set writeSet; struct timeval timeout; - int numBytes; + long numBytes; time_t start_time = time(NULL); SOCKET sockfd = info->socket; long bytes_sent = 0, byte_left = 0, num_written; @@ -164,7 +164,7 @@ static int sock_read_write( #endif if (bRead) { /* read data. */ - numBytes = recv(sockfd, buffer, bufsize, MSG_NOSIGNAL); + numBytes = (long)recv(sockfd, buffer, bufsize, MSG_NOSIGNAL); } else { byte_left = bufsize; bytes_sent = 0; diff --git a/upnp/src/genlib/service_table/service_table.c b/upnp/src/genlib/service_table/service_table.c index 88c8040..e925511 100644 --- a/upnp/src/genlib/service_table/service_table.c +++ b/upnp/src/genlib/service_table/service_table.c @@ -718,164 +718,119 @@ getSubElement( const char *element_name, * * Note : ************************************************************************/ -service_info * -getServiceList( IXML_Node * node, - service_info ** end, - char *URLBase ) +service_info *getServiceList( + IXML_Node *node, + service_info **end, + char *URLBase) { - IXML_Node *serviceList = NULL; - IXML_Node *current_service = NULL; - IXML_Node *UDN = NULL; + IXML_Node *serviceList = NULL; + IXML_Node *current_service = NULL; + IXML_Node *UDN = NULL; - IXML_Node *serviceType = NULL; - IXML_Node *serviceId = NULL; - IXML_Node *SCPDURL = NULL; - IXML_Node *controlURL = NULL; - IXML_Node *eventURL = NULL; - DOMString tempDOMString = NULL; - service_info *head = NULL; - service_info *current = NULL; - service_info *previous = NULL; - IXML_NodeList *serviceNodeList = NULL; - int NumOfServices = 0; - int i = 0; - int fail = 0; - - if( getSubElement( "UDN", node, &UDN ) && - getSubElement( "serviceList", node, &serviceList ) ) { - - serviceNodeList = ixmlElement_getElementsByTagName( ( IXML_Element - * ) - serviceList, - "service" ); - - if( serviceNodeList != NULL ) { - NumOfServices = ixmlNodeList_length( serviceNodeList ); - for( i = 0; i < NumOfServices; i++ ) { - current_service = ixmlNodeList_item( serviceNodeList, i ); - fail = 0; - - if( current ) { - current->next = - ( service_info * ) - malloc( sizeof( service_info ) ); - - previous = current; - current = current->next; - } else { - head = - ( service_info * ) - malloc( sizeof( service_info ) ); - current = head; - } - - if( !current ) { - freeServiceList( head ); - return NULL; - } - - current->next = NULL; - current->controlURL = NULL; - current->eventURL = NULL; - current->serviceType = NULL; - current->serviceId = NULL; - current->SCPDURL = NULL; - current->active = 1; - current->subscriptionList = NULL; - current->TotalSubscriptions = 0; - - if( !( current->UDN = getElementValue( UDN ) ) ) - fail = 1; - - if( ( !getSubElement( "serviceType", current_service, - &serviceType ) ) || - ( !( current->serviceType = - getElementValue( serviceType ) ) ) ) - fail = 1; - - if( ( !getSubElement( "serviceId", current_service, - &serviceId ) ) || - ( ! - ( current->serviceId = - getElementValue( serviceId ) ) ) ) - fail = 1; - - if( ( ! - ( getSubElement - ( "SCPDURL", current_service, &SCPDURL ) ) ) - || ( !( tempDOMString = getElementValue( SCPDURL ) ) ) - || - ( ! - ( current->SCPDURL = - resolve_rel_url( URLBase, tempDOMString ) ) ) ) - fail = 1; - - ixmlFreeDOMString( tempDOMString ); - tempDOMString = NULL; - - if( ( ! - ( getSubElement - ( "controlURL", current_service, &controlURL ) ) ) - || - ( !( tempDOMString = getElementValue( controlURL ) ) ) - || - ( ! - ( current->controlURL = - resolve_rel_url( URLBase, tempDOMString ) ) ) ) { - UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__, - "BAD OR MISSING CONTROL URL" ); - UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__, - "CONTROL URL SET TO NULL IN SERVICE INFO" ); - current->controlURL = NULL; - fail = 0; - } - - ixmlFreeDOMString( tempDOMString ); - tempDOMString = NULL; - - if( ( ! - ( getSubElement - ( "eventSubURL", current_service, &eventURL ) ) ) - || ( !( tempDOMString = getElementValue( eventURL ) ) ) - || - ( ! - ( current->eventURL = - resolve_rel_url( URLBase, tempDOMString ) ) ) ) { - UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__, - "BAD OR MISSING EVENT URL" ); - UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__, - "EVENT URL SET TO NULL IN SERVICE INFO" ); - current->eventURL = NULL; - fail = 0; - } - - ixmlFreeDOMString( tempDOMString ); - tempDOMString = NULL; - - if( fail ) { - freeServiceList( current ); - - if( previous ) - previous->next = NULL; - else - head = NULL; - - current = previous; - } - - } - - ixmlNodeList_free( serviceNodeList ); - } - - ( *end ) = current; - - return head; - } else { - ( *end ) = NULL; - return NULL; - } + IXML_Node *serviceType = NULL; + IXML_Node *serviceId = NULL; + IXML_Node *SCPDURL = NULL; + IXML_Node *controlURL = NULL; + IXML_Node *eventURL = NULL; + DOMString tempDOMString = NULL; + service_info *head = NULL; + service_info *current = NULL; + service_info *previous = NULL; + IXML_NodeList *serviceNodeList = NULL; + long unsigned int NumOfServices = 0; + long unsigned int i = 0; + int fail = 0; + if (getSubElement("UDN", node, &UDN) && + getSubElement("serviceList", node, &serviceList)) { + serviceNodeList = ixmlElement_getElementsByTagName( + (IXML_Element *)serviceList, "service"); + if (serviceNodeList != NULL) { + NumOfServices = ixmlNodeList_length(serviceNodeList); + for (i = 0; i < NumOfServices; i++) { + current_service = + ixmlNodeList_item(serviceNodeList, i); + fail = 0; + if (current) { + current->next = malloc(sizeof(service_info)); + previous = current; + current = current->next; + } else { + head = malloc(sizeof(service_info)); + current = head; + } + if (!current) { + freeServiceList(head); + return NULL; + } + current->next = NULL; + current->controlURL = NULL; + current->eventURL = NULL; + current->serviceType = NULL; + current->serviceId = NULL; + current->SCPDURL = NULL; + current->active = 1; + current->subscriptionList = NULL; + current->TotalSubscriptions = 0; + if (!(current->UDN = getElementValue(UDN))) + fail = 1; + if (!getSubElement("serviceType", current_service, &serviceType) || + !(current->serviceType = getElementValue(serviceType))) + fail = 1; + if (!getSubElement("serviceId", current_service, &serviceId) || + !(current->serviceId = getElementValue(serviceId))) + fail = 1; + if (!getSubElement("SCPDURL", current_service, &SCPDURL) || + !(tempDOMString = getElementValue(SCPDURL)) || + !(current->SCPDURL = resolve_rel_url(URLBase, tempDOMString))) + fail = 1; + ixmlFreeDOMString(tempDOMString); + tempDOMString = NULL; + if (!(getSubElement("controlURL", current_service, &controlURL)) || + !(tempDOMString = getElementValue(controlURL)) || + !(current->controlURL = resolve_rel_url(URLBase, tempDOMString))) { + UpnpPrintf(UPNP_INFO, GENA, __FILE__, + __LINE__, + "BAD OR MISSING CONTROL URL"); + UpnpPrintf(UPNP_INFO, GENA, __FILE__, + __LINE__, + "CONTROL URL SET TO NULL IN SERVICE INFO"); + current->controlURL = NULL; + fail = 0; + } + ixmlFreeDOMString(tempDOMString); + tempDOMString = NULL; + if (!getSubElement("eventSubURL", current_service, &eventURL) || + !(tempDOMString = getElementValue(eventURL)) || + !(current->eventURL = resolve_rel_url(URLBase, tempDOMString))) { + UpnpPrintf(UPNP_INFO, GENA, __FILE__, + __LINE__, + "BAD OR MISSING EVENT URL"); + UpnpPrintf(UPNP_INFO, GENA, __FILE__, + __LINE__, + "EVENT URL SET TO NULL IN SERVICE INFO"); + current->eventURL = NULL; + fail = 0; + } + ixmlFreeDOMString(tempDOMString); + tempDOMString = NULL; + if (fail) { + freeServiceList(current); + if (previous) + previous->next = NULL; + else + head = NULL; + current = previous; + } + } + ixmlNodeList_free(serviceNodeList); + } + (*end) = current; + return head; + } else { + (*end) = NULL; + return NULL; + } } /************************************************************************ @@ -899,39 +854,37 @@ getAllServiceList( IXML_Node * node, char *URLBase, service_info ** out_end ) { - service_info *head = NULL; - service_info *end = NULL; - service_info *next_end = NULL; - IXML_NodeList *deviceList = NULL; - IXML_Node *currentDevice = NULL; + service_info *head = NULL; + service_info *end = NULL; + service_info *next_end = NULL; + IXML_NodeList *deviceList = NULL; + IXML_Node *currentDevice = NULL; - int NumOfDevices = 0; - int i = 0; + long unsigned int NumOfDevices = 0; + long unsigned int i = 0; - ( *out_end ) = NULL; + (*out_end) = NULL; - deviceList = - ixmlElement_getElementsByTagName( ( IXML_Element * ) node, - "device" ); - if( deviceList != NULL ) { - NumOfDevices = ixmlNodeList_length( deviceList ); - for( i = 0; i < NumOfDevices; i++ ) { - currentDevice = ixmlNodeList_item( deviceList, i ); - if( head ) { - end->next = - getServiceList( currentDevice, &next_end, URLBase ); - if ( next_end ) - end = next_end; - } else - head = getServiceList( currentDevice, &end, URLBase ); + deviceList = ixmlElement_getElementsByTagName( + (IXML_Element *)node, "device"); + if (deviceList) { + NumOfDevices = ixmlNodeList_length(deviceList); + for (i = 0; i < NumOfDevices; i++) { + currentDevice = ixmlNodeList_item(deviceList, i); + if (head) { + end->next = getServiceList(currentDevice, + &next_end, URLBase); + if (next_end) + end = next_end; + } else + head = getServiceList(currentDevice, &end, + URLBase); + } + ixmlNodeList_free(deviceList); + } - } - - ixmlNodeList_free( deviceList ); - } - - ( *out_end ) = end; - return head; + (*out_end) = end; + return head; } /************************************************************************ @@ -963,8 +916,8 @@ removeServiceTable( IXML_Node * node, service_info *current_service = NULL; service_info *start_search = NULL; service_info *prev_service = NULL; - int NumOfDevices = 0; - int i = 0; + long unsigned int NumOfDevices = 0; + long unsigned int i = 0; if( getSubElement( "root", node, &root ) ) { current_service = in->serviceList; diff --git a/upnp/src/genlib/util/membuffer.c b/upnp/src/genlib/util/membuffer.c index 582ca67..dbd6807 100644 --- a/upnp/src/genlib/util/membuffer.c +++ b/upnp/src/genlib/util/membuffer.c @@ -311,33 +311,31 @@ membuffer_destroy( INOUT membuffer * m ) * * Note : ************************************************************************/ -int -membuffer_assign( INOUT membuffer * m, +int membuffer_assign( INOUT membuffer * m, IN const void *buf, IN size_t buf_len ) { - int return_code; + int return_code; - assert( m != NULL ); + assert(m != NULL); - /* set value to null */ - if( buf == NULL ) { - membuffer_destroy( m ); - return 0; - } - /* alloc mem */ - return_code = membuffer_set_size( m, buf_len ); - if( return_code != 0 ) { - return return_code; - } - /* copy */ - if( buf_len ) { - memcpy( m->buf, buf, buf_len ); - m->buf[buf_len] = 0; /* null-terminate */ - } - m->length = buf_len; + /* set value to null */ + if (buf == NULL) { + membuffer_destroy(m); + return 0; + } + /* alloc mem */ + return_code = membuffer_set_size(m, buf_len); + if (return_code != 0) + return return_code; + /* copy */ + if (buf_len) { + memcpy(m->buf, buf, buf_len); + m->buf[buf_len] = 0; /* null-terminate */ + } + m->length = buf_len; - return 0; + return 0; } /************************************************************************ @@ -411,61 +409,37 @@ membuffer_append_str( INOUT membuffer * m, return membuffer_insert( m, c_str, strlen( c_str ), m->length ); } -/************************************************************************ -* Function : membuffer_insert -* -* Parameters : -* INOUT membuffer* m ; buffer whose memory size is to be increased -* and appended. -* IN const void* buf ; source buffer whose contents will be -* copied -* IN size_t buf_len ; size of the source buffer -* int index ; index to determine the bounds while movinf the data -* -* Description : Allocates memory for the new data to be inserted. Does -* memory management by moving the data from the existing memory to -* the newly allocated memory and then appending the new data. -* -* Return : int ; -* -* Note : -************************************************************************/ -int -membuffer_insert( INOUT membuffer * m, - IN const void *buf, - IN size_t buf_len, - int index ) +int membuffer_insert(membuffer *m, const void *buf, size_t buf_len, size_t index) { - int return_code; + int return_code; - assert( m != NULL ); + assert(m != NULL); - if( index < 0 || index > ( int )m->length ) - return UPNP_E_OUTOF_BOUNDS; + if (index > m->length) + return UPNP_E_OUTOF_BOUNDS; + if (!buf || !buf_len) { + return 0; + } + /* alloc mem */ + return_code = membuffer_set_size(m, m->length + buf_len); + if (return_code) { + return return_code; + } + /* insert data */ + /* move data to right of insertion point */ + memmove(m->buf + index + buf_len, m->buf + index, m->length - index); + memcpy(m->buf + index, buf, buf_len); + m->length += buf_len; + /* null-terminate */ + m->buf[m->length] = 0; - if( buf == NULL || buf_len == 0 ) { - return 0; - } - /* alloc mem */ - return_code = membuffer_set_size( m, m->length + buf_len ); - if( return_code != 0 ) { - return return_code; - } - /* insert data */ - - /* move data to right of insertion point */ - memmove( m->buf + index + buf_len, m->buf + index, m->length - index ); - memcpy( m->buf + index, buf, buf_len ); - m->length += buf_len; - m->buf[m->length] = 0; /* null-terminate */ - - return 0; + return 0; } void membuffer_delete(membuffer *m, size_t index, size_t num_bytes) { int return_value; - int new_length; + size_t new_length; size_t copy_len; assert(m != NULL); diff --git a/upnp/src/genlib/util/util.c b/upnp/src/genlib/util/util.c index 6a44c27..9dd472a 100644 --- a/upnp/src/genlib/util/util.c +++ b/upnp/src/genlib/util/util.c @@ -58,7 +58,7 @@ void namecopy(char dest[NAME_SIZE], const char *src) void linecopylen(char dest[LINE_SIZE], const char *src, size_t srclen) { - int len; + size_t len; len = srclen < (LINE_SIZE - 1) ? srclen : (LINE_SIZE - 1); strncpy(dest, src, len); diff --git a/upnp/src/inc/membuffer.h b/upnp/src/inc/membuffer.h index bbc3e5b..d00dcc5 100644 --- a/upnp/src/inc/membuffer.h +++ b/upnp/src/inc/membuffer.h @@ -257,26 +257,22 @@ int membuffer_append( INOUT membuffer* m, IN const void* buf, IN size_t buf_len ************************************************************************/ int membuffer_append_str( INOUT membuffer* m, IN const char* c_str ); -/************************************************************************ -* Function : membuffer_insert -* -* Parameters : -* INOUT membuffer* m ; buffer whose memory size is to be increased -* and appended. -* IN const void* buf ; source buffer whose contents will be -* copied -* IN size_t buf_len ; size of the source buffer -* int index ; index to determine the bounds while movinf the data -* -* Description : Allocates memory for the new data to be inserted. Does -* memory management by moving the data from the existing memory to -* the newly allocated memory and then appending the new data. -* -* Return : int ; -* -* Note : -************************************************************************/ -int membuffer_insert( INOUT membuffer* m, IN const void* buf, IN size_t buf_len, int index ); +/*! + * \brief Allocates memory for the new data to be inserted. Does + * memory management by moving the data from the existing memory to + * the newly allocated memory and then appending the new data. + * + * \return 0 if successful, error code if error. + */ +int membuffer_insert( + /* [in,out] Buffer whose memory size is to be increased and appended. */ + membuffer *m, + /* [in] source buffer whose contents will be copied. */ + const void *buf, + /* [in] size of the source buffer. */ + size_t buf_len, + /* [in] index to determine the bounds while movinf the data. */ + size_t index); /*! diff --git a/upnp/src/inc/ssdplib.h b/upnp/src/inc/ssdplib.h index b756941..0cc8c92 100644 --- a/upnp/src/inc/ssdplib.h +++ b/upnp/src/inc/ssdplib.h @@ -234,7 +234,7 @@ static inline void ssdp_handle_device_request( * Parameters: * IN http_message_t* hmsg: SSDP message from the device * IN struct sockaddr* dest_addr: Address of the device -* IN xboolean timeout: timeout kept by the control point while sending +* IN int timeout: timeout kept by the control point while sending * search message * IN void* cookie: Cookie stored by the control point application. * This cookie will be returned to the control point @@ -251,7 +251,7 @@ static inline void ssdp_handle_device_request( void ssdp_handle_ctrlpt_msg( IN http_message_t *hmsg, IN struct sockaddr *dest_addr, - IN xboolean timeout, + IN int timeout, IN void *cookie); /************************************************************************ diff --git a/upnp/src/soap/soap_ctrlpt.c b/upnp/src/soap/soap_ctrlpt.c index f4bc97e..212ddf4 100644 --- a/upnp/src/soap/soap_ctrlpt.c +++ b/upnp/src/soap/soap_ctrlpt.c @@ -58,145 +58,115 @@ #define SOAP_ACTION_RESP_ERROR 3 #define SOAP_VAR_RESP_ERROR 4 -/**************************************************************************** -* Function : dom_cmp_name -* -* Parameters : -* IN char *name : lookup name -* IN IXML_Node *node : xml node -* -* Description : This function compares 'name' and node's name -* -* Return : int -* 0 if both are equal; 1 if not equal, and UPNP_E_OUTOF_MEMORY -* -* Note : -****************************************************************************/ -static int -dom_cmp_name( IN char *name, - IN IXML_Node * node ) +/*! + * \brief Compares 'name' and node's name. + * + * \return 0 if both are equal; 1 if not equal, and UPNP_E_OUTOF_MEMORY. + */ +static int dom_cmp_name( + /* [in] lookup name. */ + const char *name, + /* [in] xml node. */ + IXML_Node *node) { - const DOMString node_name = NULL; - memptr nameptr, - dummy; - int ret_code; + const DOMString node_name = NULL; + memptr nameptr; + memptr dummy; + int ret_code; - assert( name ); - assert( node ); + assert(name); + assert(node); - node_name = ixmlNode_getNodeName( node ); - if( node_name == NULL ) { - return UPNP_E_OUTOF_MEMORY; - } + node_name = ixmlNode_getNodeName(node); + if (node_name == NULL) + return UPNP_E_OUTOF_MEMORY; + if (strcmp(name, node_name) == 0) + ret_code = 0; + else if (matchstr((char *)node_name, strlen(node_name), + "%s:%s%0", &dummy, &nameptr) == PARSE_OK && + strcmp(nameptr.buf, name) == 0) + ret_code = 0; + else + /* names are not the same */ + ret_code = 1; - if( strcmp( name, node_name ) == 0 ) { - ret_code = 0; - } else if( matchstr( ( char * )node_name, strlen( node_name ), - "%s:%s%0", &dummy, &nameptr ) == PARSE_OK && - strcmp( nameptr.buf, name ) == 0 ) { - ret_code = 0; - } else { - ret_code = 1; /* names are not the same */ - } - - return ret_code; + return ret_code; } -/**************************************************************************** -* Function : dom_find_node -* -* Parameters : -* IN char* node_name : name of the node -* IN IXML_Node *start_node : complete xml node -* OUT IXML_Node ** matching_node : matched node -* -* Description : This function goes thru each child of 'start_node' -* looking for a node having the name 'node_name'. -* -* Return : int -* return UPNP_E_SUCCESS if successful else returns appropriate error -* -* Note : -****************************************************************************/ -static int -dom_find_node( IN char *node_name, - IN IXML_Node * start_node, - OUT IXML_Node ** matching_node ) +/*! + * \brief Goes thru each child of 'start_node' looking for a node having + * the name 'node_name'. + * + * \return UPNP_E_SUCCESS if successful else returns appropriate error. + */ +static int dom_find_node( + /* [in] name of the node. */ + const char *node_name, + /* [in] complete xml node. */ + IXML_Node *start_node, + /* [out] matched node. */ + IXML_Node **matching_node) { - IXML_Node *node; + IXML_Node *node; - /* invalid args */ - if( node_name == NULL || start_node == NULL ) { - return UPNP_E_NOT_FOUND; - } + /* invalid args */ + if (!node_name || !start_node) + return UPNP_E_NOT_FOUND; + node = ixmlNode_getFirstChild(start_node); + while (node != NULL) { + /* match name */ + if (dom_cmp_name(node_name, node) == 0) { + *matching_node = node; + return UPNP_E_SUCCESS; + } + /* free and next node */ + node = ixmlNode_getNextSibling(node); + } - node = ixmlNode_getFirstChild( start_node ); - while( node != NULL ) { - /* match name */ - if( dom_cmp_name( node_name, node ) == 0 ) { - *matching_node = node; - return UPNP_E_SUCCESS; - } - /* free and next node */ - node = ixmlNode_getNextSibling( node ); /* next node */ - } - - return UPNP_E_NOT_FOUND; + return UPNP_E_NOT_FOUND; } -/**************************************************************************** -* Function : dom_find_deep_node -* -* Parameters : -* IN char* names[] : array of names -* IN int num_names : size of array -* IN IXML_Node *start_node : Node from where it should should be -* searched -* OUT IXML_Node ** matching_node : Node that matches the last name -* of the array -* -* Description : This function searches for the node specifed by the last -* name in the 'name' array. -* -* Return : int -* return UPNP_E_SUCCESS if successful else returns appropriate error -* Note : -****************************************************************************/ -static int -dom_find_deep_node( IN char *names[], - IN int num_names, - IN IXML_Node * start_node, - OUT IXML_Node ** matching_node ) +/*! + * \brief Searches for the node specifed by the last name in the 'name' array. + * + * \return UPNP_E_SUCCESS if successful, else returns appropriate error. + */ +static int dom_find_deep_node( + /* [in] array of names. */ + const char *names[], + /* [in] size of array. */ + int num_names, + /* [in] Node from where it should should be searched. */ + IXML_Node *start_node, + /* [out] Node that matches the last name of the array. */ + IXML_Node **matching_node) { - int i; - IXML_Node *node; - IXML_Node *match_node; + int i; + IXML_Node *node; + IXML_Node *match_node; - assert( num_names > 0 ); + assert(num_names > 0); - node = start_node; - if( dom_cmp_name( names[0], start_node ) == 0 ) { - if( num_names == 1 ) { - *matching_node = start_node; - return UPNP_E_SUCCESS; - } - } + node = start_node; + if (dom_cmp_name(names[0], start_node) == 0) { + if (num_names == 1) { + *matching_node = start_node; + return UPNP_E_SUCCESS; + } + } + for (i = 1; i < num_names; i++) { + if (dom_find_node(names[i], node, &match_node) != UPNP_E_SUCCESS) + return UPNP_E_NOT_FOUND; + if (i == num_names - 1) { + *matching_node = match_node; + return UPNP_E_SUCCESS; + } + /* try again */ + node = match_node; + } - for( i = 1; i < num_names; i++ ) { - if( dom_find_node( names[i], node, &match_node ) != - UPNP_E_SUCCESS ) { - return UPNP_E_NOT_FOUND; - } - - if( i == num_names - 1 ) { - *matching_node = match_node; - return UPNP_E_SUCCESS; - } - - node = match_node; /* try again */ - } - - return UPNP_E_NOT_FOUND; /* this line not reached */ + /* this line not reached */ + return UPNP_E_NOT_FOUND; } /**************************************************************************** @@ -290,41 +260,32 @@ get_action_name( IN char *action, return ret_code == PARSE_OK ? 0 : -1; } -/**************************************************************************** -* Function : add_man_header -* -* Parameters : -* INOUT membuffer* headers : HTTP header -* -* Description : This function adds "MAN" field in the HTTP header -* -* Return : int -* returns 0 on success; UPNP_E_OUTOFMEMORY on error -* -* Note : -****************************************************************************/ -static UPNP_INLINE int -add_man_header( INOUT membuffer * headers ) +/*! + * \brief Adds "MAN" field in the HTTP header. + * + * \return 0 on success, UPNP_E_OUTOFMEMORY on error. + */ +static UPNP_INLINE int add_man_header( + /* [in,out] HTTP header. */ + membuffer *headers) { - char *soap_action_hdr; - char *man_hdr = "MAN: \"http://schemas.xmlsoap.org/soap/envelope/\"; " - "ns=01\r\n01-"; + size_t n; + char *soap_action_hdr; + const char *man_hdr = + "MAN: \"http://schemas.xmlsoap.org/soap/envelope/\"; ns=01\r\n01-"; - /* change POST to M-POST */ - if( membuffer_insert( headers, "M-", 2, 0 ) != 0 ) { - return UPNP_E_OUTOF_MEMORY; - } + /* change POST to M-POST */ + if (membuffer_insert(headers, "M-", 2, 0) != 0) + return UPNP_E_OUTOF_MEMORY; + soap_action_hdr = strstr(headers->buf, "SOAPACTION:"); + /* can't fail */ + assert(soap_action_hdr != NULL); + /* insert MAN header */ + n = (size_t)(soap_action_hdr - headers->buf); + if (membuffer_insert(headers, man_hdr, strlen(man_hdr), n)) + return UPNP_E_OUTOF_MEMORY; - soap_action_hdr = strstr( headers->buf, "SOAPACTION:" ); - assert( soap_action_hdr != NULL ); /* can't fail */ - - /* insert MAN header */ - if( membuffer_insert( headers, man_hdr, strlen( man_hdr ), - soap_action_hdr - headers->buf ) != 0 ) { - return UPNP_E_OUTOF_MEMORY; - } - - return 0; + return 0; } /**************************************************************************** @@ -411,161 +372,129 @@ get_response_value( IN http_message_t * hmsg, OUT IXML_Node ** action_value, OUT DOMString * str_value ) { - IXML_Node *node = NULL; - IXML_Node *root_node = NULL; - IXML_Node *error_node = NULL; - IXML_Document *doc = NULL; - char *node_str = NULL; - const char *temp_str = NULL; - DOMString error_node_str = NULL; - int err_code; - xboolean done = FALSE; - char *names[5]; - const DOMString nodeValue; + IXML_Node *node = NULL; + IXML_Node *root_node = NULL; + IXML_Node *error_node = NULL; + IXML_Document *doc = NULL; + char *node_str = NULL; + const char *temp_str = NULL; + DOMString error_node_str = NULL; + int err_code = UPNP_E_BAD_RESPONSE; /* default error */ ; + int done = FALSE; + const char *names[5]; + const DOMString nodeValue; - err_code = UPNP_E_BAD_RESPONSE; /* default error */ + /* only 200 and 500 status codes are relevant */ + if ((hmsg->status_code != HTTP_OK && + hmsg->status_code != HTTP_INTERNAL_SERVER_ERROR) || + !has_xml_content_type(hmsg)) + goto error_handler; + if (ixmlParseBufferEx(hmsg->entity.buf, &doc) != IXML_SUCCESS) + goto error_handler; + root_node = ixmlNode_getFirstChild((IXML_Node *) doc); + if (root_node == NULL) + goto error_handler; + if (code == SOAP_ACTION_RESP) { + /* try reading soap action response */ + assert(action_value != NULL); - /* only 200 and 500 status codes are relevant */ - if( ( hmsg->status_code != HTTP_OK && - hmsg->status_code != HTTP_INTERNAL_SERVER_ERROR ) || - !has_xml_content_type( hmsg ) ) { + *action_value = NULL; + names[0] = "Envelope"; + names[1] = "Body"; + names[2] = name; + if (dom_find_deep_node(names, 3, root_node, &node) == + UPNP_E_SUCCESS) { + node_str = ixmlPrintNode(node); + if (node_str == NULL) { + err_code = UPNP_E_OUTOF_MEMORY; + goto error_handler; + } + if (ixmlParseBufferEx(node_str, + (IXML_Document **) action_value) + != IXML_SUCCESS) { + err_code = UPNP_E_BAD_RESPONSE; + goto error_handler; + } + err_code = SOAP_ACTION_RESP; + done = TRUE; + } + } else if (code == SOAP_VAR_RESP) { + /* try reading var response */ + assert(str_value != NULL); - goto error_handler; - } + *str_value = NULL; + names[0] = "Envelope"; + names[1] = "Body"; + names[2] = "QueryStateVariableResponse"; + names[3] = "return"; + if (dom_find_deep_node(names, 4, root_node, &node) + == UPNP_E_SUCCESS) { + nodeValue = get_node_value(node); + if (nodeValue == NULL) + goto error_handler; + *str_value = ixmlCloneDOMString(nodeValue); + err_code = SOAP_VAR_RESP; + done = TRUE; + } + } + if (!done) { + /* not action or var resp; read error code and description */ + *str_value = NULL; + names[0] = "Envelope"; + names[1] = "Body"; + names[2] = "Fault"; + names[3] = "detail"; + names[4] = "UPnPError"; + if (dom_find_deep_node(names, 5, root_node, &error_node) != + UPNP_E_SUCCESS) + goto error_handler; + if (dom_find_node("errorCode", error_node, &node) != + UPNP_E_SUCCESS) + goto error_handler; + temp_str = get_node_value(node); + if (!temp_str) + goto error_handler; + *upnp_error_code = atoi(temp_str); + if (*upnp_error_code < 400) { + err_code = *upnp_error_code; + goto error_handler; /* bad SOAP error code */ + } + if (code == SOAP_VAR_RESP) { + if (dom_find_node("errorDescription", error_node, &node) + != UPNP_E_SUCCESS) { + goto error_handler; + } + nodeValue = get_node_value(node); + if (nodeValue == NULL) { + goto error_handler; + } + *str_value = ixmlCloneDOMString(nodeValue); + if (*str_value == NULL) { + goto error_handler; + } + err_code = SOAP_VAR_RESP_ERROR; + } else if (code == SOAP_ACTION_RESP) { + error_node_str = ixmlPrintNode(error_node); + if (error_node_str == NULL) { + err_code = UPNP_E_OUTOF_MEMORY; + goto error_handler; + } + if (ixmlParseBufferEx(error_node_str, + (IXML_Document **) action_value) + != IXML_SUCCESS) { + err_code = UPNP_E_BAD_RESPONSE; - if( ixmlParseBufferEx( hmsg->entity.buf, &doc ) != IXML_SUCCESS ) { + goto error_handler; + } + err_code = SOAP_ACTION_RESP_ERROR; + } + } - goto error_handler; - } - - root_node = ixmlNode_getFirstChild( ( IXML_Node * ) doc ); - if( root_node == NULL ) { - - goto error_handler; - } - - if( code == SOAP_ACTION_RESP ) { - /* */ - /* try reading soap action response */ - /* */ - assert( action_value != NULL ); - - *action_value = NULL; - - names[0] = "Envelope"; - names[1] = "Body"; - names[2] = name; - if( dom_find_deep_node( names, 3, root_node, &node ) == - UPNP_E_SUCCESS ) { - node_str = ixmlPrintNode( node ); - if( node_str == NULL ) { - err_code = UPNP_E_OUTOF_MEMORY; - goto error_handler; - } - - if( ixmlParseBufferEx( node_str, - ( IXML_Document ** ) action_value ) != - IXML_SUCCESS ) { - err_code = UPNP_E_BAD_RESPONSE; - goto error_handler; - } - - err_code = SOAP_ACTION_RESP; - done = TRUE; - } - } else if( code == SOAP_VAR_RESP ) { - /* try reading var response */ - assert( str_value != NULL ); - *str_value = NULL; - - names[0] = "Envelope"; - names[1] = "Body"; - names[2] = "QueryStateVariableResponse"; - names[3] = "return"; - if( dom_find_deep_node( names, 4, root_node, &node ) - == UPNP_E_SUCCESS ) { - nodeValue = get_node_value( node ); - if( nodeValue == NULL ) { - goto error_handler; - } - - *str_value = ixmlCloneDOMString( nodeValue ); - err_code = SOAP_VAR_RESP; - done = TRUE; - } - } - - if( !done ) { - /* not action or var resp; read error code and description */ - *str_value = NULL; - - names[0] = "Envelope"; - names[1] = "Body"; - names[2] = "Fault"; - names[3] = "detail"; - names[4] = "UPnPError"; - if( dom_find_deep_node( names, 5, root_node, &error_node ) - != UPNP_E_SUCCESS ) { - goto error_handler; - } - - if( dom_find_node( "errorCode", error_node, &node ) - != UPNP_E_SUCCESS ) { - goto error_handler; - } - - temp_str = get_node_value( node ); - if( temp_str == NULL ) { - goto error_handler; - } - - *upnp_error_code = atoi( temp_str ); - if( *upnp_error_code < 400 ) { - err_code = *upnp_error_code; - goto error_handler; /* bad SOAP error code */ - } - - if( code == SOAP_VAR_RESP ) { - if( dom_find_node( "errorDescription", error_node, &node ) - != UPNP_E_SUCCESS ) { - goto error_handler; - } - - nodeValue = get_node_value( node ); - if( nodeValue == NULL ) { - goto error_handler; - } - *str_value = ixmlCloneDOMString( nodeValue ); - if( *str_value == NULL ) { - goto error_handler; - } - err_code = SOAP_VAR_RESP_ERROR; - } - - else if( code == SOAP_ACTION_RESP ) { - error_node_str = ixmlPrintNode( error_node ); - if( error_node_str == NULL ) { - err_code = UPNP_E_OUTOF_MEMORY; - goto error_handler; - } - - if( ixmlParseBufferEx( error_node_str, - ( IXML_Document ** ) action_value ) != - IXML_SUCCESS ) { - err_code = UPNP_E_BAD_RESPONSE; - - goto error_handler; - } - err_code = SOAP_ACTION_RESP_ERROR; - } - } - - error_handler: - - ixmlDocument_free( doc ); - ixmlFreeDOMString( node_str ); - ixmlFreeDOMString( error_node_str ); - return err_code; + error_handler: + ixmlDocument_free(doc); + ixmlFreeDOMString(node_str); + ixmlFreeDOMString(error_node_str); + return err_code; } /**************************************************************************** @@ -601,15 +530,15 @@ SoapSendAction( IN char *action_url, uri_type url; int upnp_error_code; char *upnp_error_str; - xboolean got_response = FALSE; + int got_response = FALSE; off_t content_length; - char *xml_start = + const char *xml_start = "\r\n" ""; - char *xml_end = + const char *xml_end = "\r\n" "\r\n\r\n"; size_t xml_start_len; @@ -655,7 +584,7 @@ SoapSendAction( IN char *action_url, /* make request msg */ request.size_inc = 50; - content_length = xml_start_len + action_str_len + xml_end_len; + content_length = (off_t)(xml_start_len + action_str_len + xml_end_len); if (http_MakeMessage( &request, 1, 1, "q" "N" "s" "sssbsc" "Uc" "b" "b" "b", @@ -725,12 +654,12 @@ error_handler: * returns UPNP_E_SUCCESS if successful else returns appropriate error * Note : ****************************************************************************/ -int -SoapSendActionEx( IN char *action_url, - IN char *service_type, - IN IXML_Document * header, - IN IXML_Document * action_node, - OUT IXML_Document ** response_node ) +int SoapSendActionEx( + IN char *action_url, + IN char *service_type, + IN IXML_Document * header, + IN IXML_Document * action_node, + OUT IXML_Document ** response_node ) { char *xml_header_str = NULL; char *action_str = NULL; @@ -743,19 +672,18 @@ SoapSendActionEx( IN char *action_url, uri_type url; int upnp_error_code; char *upnp_error_str; - xboolean got_response = FALSE; - - char *xml_start = + int got_response = FALSE; + const char *xml_start = "\r\n"; - char *xml_header_start = + const char *xml_header_start = "\r\n"; - char *xml_header_end = + const char *xml_header_end = "\r\n"; - char *xml_body_start = + const char *xml_body_start = ""; - char *xml_end = + const char *xml_end = "\r\n" "\r\n"; size_t xml_start_len; @@ -816,10 +744,9 @@ SoapSendActionEx( IN char *action_url, /* make request msg */ request.size_inc = 50; - content_length = - xml_start_len + - xml_header_start_len + xml_header_str_len + xml_header_end_len + - xml_body_start_len + action_str_len + xml_end_len; + content_length = (off_t)(xml_start_len + xml_header_start_len + + xml_header_str_len + xml_header_end_len + + xml_body_start_len + action_str_len + xml_end_len); if (http_MakeMessage( &request, 1, 1, "q" "N" "s" "sssbsc" "Uc" "b" "b" "b" "b" "b" "b" "b", @@ -903,33 +830,30 @@ SoapGetServiceVarStatus( IN char *action_url, int ret_code; http_parser_t response; int upnp_error_code; - off_t content_length; - char *xml_start = + const char *xml_start = "\r\n" "\r\n" "\r\n" ""; - - char *xml_end = + const char *xml_end = "\r\n" "\r\n" "\r\n" "\r\n"; *var_value = NULL; /* return NULL in case of an error */ - membuffer_init( &request ); - /* get host hdr and url path */ if( get_host_and_path( action_url, &host, &path, &url ) == -1 ) { return UPNP_E_INVALID_URL; } /* make headers */ request.size_inc = 50; - content_length = strlen( xml_start ) + strlen( var_name ) + strlen( xml_end ); + content_length = (off_t)(strlen(xml_start) + strlen(var_name) + + strlen(xml_end)); if (http_MakeMessage( &request, 1, 1, "Q" "sbc" "N" "s" "sc" "Ucc" "sss", @@ -950,9 +874,7 @@ SoapGetServiceVarStatus( IN char *action_url, /* get variable value from the response */ ret_code = get_response_value( &response.msg, SOAP_VAR_RESP, NULL, &upnp_error_code, NULL, var_value ); - httpmsg_destroy( &response.msg ); - if( ret_code == SOAP_VAR_RESP ) { return UPNP_E_SUCCESS; } else if( ret_code == SOAP_VAR_RESP_ERROR ) { diff --git a/upnp/src/soap/soap_device.c b/upnp/src/soap/soap_device.c index 5fd29b0..5415672 100644 --- a/upnp/src/soap/soap_device.c +++ b/upnp/src/soap/soap_device.c @@ -88,82 +88,68 @@ static UPNP_INLINE int get_request_type( /*! [out] SOAP action name. */ memptr *action_name) { - memptr value; - memptr ns_value, - dummy_quote; - http_header_t *hdr; - char save_char; - char *s; - membuffer soap_action_name; + memptr value; + memptr ns_value, dummy_quote; + http_header_t *hdr; + char save_char; + char *s; + membuffer soap_action_name; + size_t n; - /* find soapaction header */ - if( request->method == SOAPMETHOD_POST ) { - if( httpmsg_find_hdr( request, HDR_SOAPACTION, &value ) - == NULL ) { - return SREQ_HDR_NOT_FOUND; - } - } else { - /* M-POST */ - /* get NS value from MAN header */ - hdr = httpmsg_find_hdr( request, HDR_MAN, &value ); - if( hdr == NULL ) { - return SREQ_HDR_NOT_FOUND; - } + /* find soapaction header */ + if (request->method == SOAPMETHOD_POST) { + if (!httpmsg_find_hdr(request, HDR_SOAPACTION, &value)) + return SREQ_HDR_NOT_FOUND; + } else { + /* M-POST */ + /* get NS value from MAN header */ + hdr = httpmsg_find_hdr(request, HDR_MAN, &value); + if (hdr == NULL) + return SREQ_HDR_NOT_FOUND; + if (matchstr(value.buf, value.length, "%q%i ; ns = %s", + &dummy_quote, &ns_value) != 0) + return SREQ_BAD_HDR_FORMAT; + /* create soapaction name header */ + membuffer_init(&soap_action_name); + if (membuffer_assign(&soap_action_name, + ns_value.buf, ns_value.length) == UPNP_E_OUTOF_MEMORY || + membuffer_append_str(&soap_action_name, + "-SOAPACTION") == UPNP_E_OUTOF_MEMORY) { + membuffer_destroy(&soap_action_name); + return UPNP_E_OUTOF_MEMORY; + } + hdr = httpmsg_find_hdr_str(request, soap_action_name.buf); + membuffer_destroy(&soap_action_name); + if (!hdr) + return SREQ_HDR_NOT_FOUND; + value.buf = hdr->value.buf; + value.length = hdr->value.length; + } + /* determine type */ + save_char = value.buf[value.length]; + value.buf[value.length] = '\0'; + s = strchr(value.buf, '#'); + if (s == NULL) { + value.buf[value.length] = save_char; + return SREQ_BAD_HDR_FORMAT; + } + /* move to value */ + s++; + n = value.length - (size_t)(s - value.buf); + if (matchstr(s, n, "%s", action_name) != PARSE_OK) { + value.buf[value.length] = save_char; + return SREQ_BAD_HDR_FORMAT; + } + /* action name or variable ? */ + if (memptr_cmp(action_name, "QueryStateVariable") == 0) { + /* query variable */ + action_name->buf = NULL; + action_name->length = 0; + } + /* restore */ + value.buf[value.length] = save_char; - if( matchstr( value.buf, value.length, "%q%i ; ns = %s", - &dummy_quote, &ns_value ) != 0 ) { - return SREQ_BAD_HDR_FORMAT; - } - /* create soapaction name header */ - membuffer_init( &soap_action_name ); - if( ( membuffer_assign( &soap_action_name, - ns_value.buf, ns_value.length ) - == UPNP_E_OUTOF_MEMORY ) || - ( membuffer_append_str( &soap_action_name, - "-SOAPACTION" ) == - UPNP_E_OUTOF_MEMORY ) - ) { - membuffer_destroy( &soap_action_name ); - return UPNP_E_OUTOF_MEMORY; - } - - hdr = httpmsg_find_hdr_str( request, soap_action_name.buf ); - membuffer_destroy( &soap_action_name ); - if( hdr == NULL ) { - return SREQ_HDR_NOT_FOUND; - } - - value.buf = hdr->value.buf; - value.length = hdr->value.length; - } - - /* determine type */ - save_char = value.buf[value.length]; - value.buf[value.length] = '\0'; - - s = strchr( value.buf, '#' ); - if( s == NULL ) { - value.buf[value.length] = save_char; - return SREQ_BAD_HDR_FORMAT; - } - - /* move to value */ - s++; - - if( matchstr( s, value.length - ( s - value.buf ), "%s", - action_name ) != PARSE_OK ) { - value.buf[value.length] = save_char; - return SREQ_BAD_HDR_FORMAT; - } - /* action name or variable ? */ - if( memptr_cmp( action_name, "QueryStateVariable" ) == 0 ) { - /* query variable */ - action_name->buf = NULL; - action_name->length = 0; - } - /* restore */ - value.buf[value.length] = save_char; - return 0; + return 0; } /**************************************************************************** @@ -189,8 +175,8 @@ send_error_response( IN SOCKINFO * info, { off_t content_length; int timeout_secs = SOAP_TIMEOUT; - int major, - minor; + int major; + int minor; const char *start_body = /* "\n" required?? */ "\n" "\n" ""; - const char *mid_body = "\n" ""; - const char *end_body = "\n" "\n" "\n" "\n" "\n" "\n"; - char err_code_str[30]; - membuffer headers; sprintf( err_code_str, "%d", error_code ); - /* calc body len */ - content_length = strlen( start_body ) + strlen( err_code_str ) + - strlen( mid_body ) + strlen( err_msg ) + strlen( end_body ); - + content_length = (off_t)(strlen(start_body) + strlen(err_code_str) + + strlen(mid_body) + strlen(err_msg) + strlen(end_body)); http_CalcResponseVersion( hmsg->major_version, hmsg->minor_version, &major, &minor ); - /* make headers */ membuffer_init( &headers ); if (http_MakeMessage( @@ -242,7 +221,6 @@ send_error_response( IN SOCKINFO * info, /* send err msg */ http_SendMessage( info, &timeout_secs, "b", headers.buf, headers.length ); - membuffer_destroy( &headers ); } @@ -276,23 +254,18 @@ send_var_query_response( IN SOCKINFO * info, "\n" "\n" ""; - const char *end_body = "\n" "\n" "\n" "\n"; - membuffer response; http_CalcResponseVersion( hmsg->major_version, hmsg->minor_version, &major, &minor ); - - content_length = strlen( start_body ) + strlen( var_value ) + - strlen( end_body ); - + content_length = (off_t)(strlen(start_body) + strlen(var_value) + + strlen(end_body)); /* make headers */ - membuffer_init( &response ); - + membuffer_init(&response); if (http_MakeMessage( &response, major, minor, "RNsDsSXcc" "sss", @@ -302,15 +275,13 @@ send_var_query_response( IN SOCKINFO * info, "EXT:\r\n", X_USER_AGENT, start_body, var_value, end_body ) != 0 ) { - membuffer_destroy( &response ); + membuffer_destroy(&response); return; /* out of mem */ } - /* send msg */ - http_SendMessage( info, &timeout_secs, "b", - response.buf, response.length ); - - membuffer_destroy( &response ); + http_SendMessage(info, &timeout_secs, "b", + response.buf, response.length); + membuffer_destroy(&response); } /**************************************************************************** @@ -475,81 +446,72 @@ check_soap_action_header( IN http_message_t * request, IN const char *urn, OUT char **actionName ) { - memptr header_name; - http_header_t *soap_action_header = NULL; - char *ns_compare = NULL; - int tempSize = 0; - int ret_code = UPNP_E_SUCCESS; - char *temp_header_value = NULL; - char *temp = NULL; - char *temp2 = NULL; + memptr header_name; + http_header_t *soap_action_header = NULL; + char *ns_compare = NULL; + size_t tempSize = 0; + int ret_code = UPNP_E_SUCCESS; + char *temp_header_value = NULL; + char *temp = NULL; + char *temp2 = NULL; - /* check soap action header */ - soap_action_header = httpmsg_find_hdr( request, HDR_SOAPACTION, - &header_name ); + /* check soap action header */ + soap_action_header = httpmsg_find_hdr(request, HDR_SOAPACTION, + &header_name); + if (!soap_action_header) { + ret_code = UPNP_E_INVALID_ACTION; + return ret_code; + } + if (soap_action_header->value.length <= 0) { + ret_code = UPNP_E_INVALID_ACTION; + return ret_code; + } + temp_header_value = malloc(soap_action_header->value.length + 1); + if (!temp_header_value) { + ret_code = UPNP_E_OUTOF_MEMORY; + free(temp_header_value); + return ret_code; + } + strncpy(temp_header_value, soap_action_header->value.buf, + soap_action_header->value.length); + temp_header_value[soap_action_header->value.length] = 0; + temp = strchr(temp_header_value, '#'); + if (!temp) { + free(temp_header_value); + ret_code = UPNP_E_INVALID_ACTION; + return ret_code; + } - if( !soap_action_header ) { - ret_code = UPNP_E_INVALID_ACTION; - return ret_code; - } + (*temp) = 0; /* temp make string */ - if( soap_action_header->value.length <= 0 ) { - ret_code = UPNP_E_INVALID_ACTION; - return ret_code; - } + /* check to see if it is Query State Variable or + * Service Action */ + tempSize = strlen(urn) + 2; + ns_compare = malloc(tempSize); + if (!ns_compare) { + ret_code = UPNP_E_OUTOF_MEMORY; + free(temp_header_value); + return ret_code; + } + snprintf(ns_compare, tempSize, "\"%s", urn); + if (strcmp(temp_header_value, ns_compare)) + ret_code = UPNP_E_INVALID_ACTION; + else { + ret_code = UPNP_E_SUCCESS; + temp++; + temp2 = strchr(temp, '\"'); + /* remove ending " if present */ + if (temp2) + (*temp2) = 0; + if (*temp) + (*actionName) = strdup(temp); + if (!*actionName) + ret_code = UPNP_E_OUTOF_MEMORY; + } - temp_header_value = - ( char * )malloc( soap_action_header->value.length + 1 ); - - if( !temp_header_value ) { - ret_code = UPNP_E_OUTOF_MEMORY; - free( temp_header_value ); - return ret_code; - } - - strncpy( temp_header_value, soap_action_header->value.buf, - soap_action_header->value.length ); - temp_header_value[soap_action_header->value.length] = 0; - - temp = strchr( temp_header_value, '#' ); - if( !temp ) { - free( temp_header_value ); - ret_code = UPNP_E_INVALID_ACTION; - return ret_code; - } - - ( *temp ) = 0; /* temp make string */ - - /* check to see if it is Query State Variable or - * Service Action */ - tempSize = strlen( urn ) + 2; - ns_compare = ( char * )malloc( tempSize ); - if( !ns_compare ) { - ret_code = UPNP_E_OUTOF_MEMORY; - free( temp_header_value ); - return ret_code; - } - snprintf( ns_compare, tempSize, "\"%s", urn ); - if( strcmp( temp_header_value, ns_compare ) ) { - ret_code = UPNP_E_INVALID_ACTION; - } else { - ret_code = UPNP_E_SUCCESS; - temp++; - temp2 = strchr( temp, '\"' ); - if( temp2 ) /* remove ending " if present */ - { - ( *temp2 ) = 0; - } - if( *temp ) - ( *actionName ) = strdup( temp ); - if( !*actionName ) { - ret_code = UPNP_E_OUTOF_MEMORY; - } - } - - free( temp_header_value ); - free( ns_compare ); - return ret_code; + free(temp_header_value); + free(ns_compare); + return ret_code; } /**************************************************************************** @@ -686,12 +648,12 @@ send_action_response( IN SOCKINFO * info, off_t content_length; int ret_code; int timeout_secs = SOAP_TIMEOUT; - static char *start_body = + static const char *start_body = /*"" required?? */ "\n"; - static char *end_body = " "; + static const char *end_body = " "; /* init */ http_CalcResponseVersion( request->major_version, @@ -700,14 +662,10 @@ send_action_response( IN SOCKINFO * info, err_code = UPNP_E_OUTOF_MEMORY; /* one error only */ /* get xml */ xml_response = ixmlPrintNode( ( IXML_Node * ) action_resp ); - if( xml_response == NULL ) { + if (!xml_response) goto error_handler; - } - - content_length = - strlen( start_body ) + - strlen( xml_response ) + - strlen( end_body ); + content_length = (off_t)(strlen(start_body) + strlen(xml_response) + + strlen(end_body)); /* make headers */ if (http_MakeMessage( &headers, major, minor, @@ -725,13 +683,11 @@ send_action_response( IN SOCKINFO * info, start_body, strlen( start_body ), xml_response, strlen( xml_response ), end_body, strlen( end_body ) ); - if( ret_code != 0 ) { UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__, "Failed to send response: err code = %d\n", ret_code ); } - err_code = 0; error_handler: @@ -996,9 +952,8 @@ error_handler: ixmlDocument_free( action.ActionResult ); ixmlDocument_free( resp_node ); action_name.buf[action_name.length] = save_char; /* restore */ - if( err_code != 0 ) { + if( err_code != 0 ) send_error_response( info, err_code, err_str, request ); - } } /**************************************************************************** @@ -1018,56 +973,49 @@ error_handler: * * Note : ****************************************************************************/ -void -soap_device_callback( IN http_parser_t * parser, - IN http_message_t * request, - INOUT SOCKINFO * info ) +void soap_device_callback(IN http_parser_t *parser, IN http_message_t *request, + INOUT SOCKINFO *info) { - int err_code; - const char *err_str; - memptr action_name; - IXML_Document *xml_doc = NULL; + int err_code; + const char *err_str; + memptr action_name; + IXML_Document *xml_doc = NULL; - /* set default error */ - err_code = SOAP_INVALID_ACTION; - err_str = Soap_Invalid_Action; + /* set default error */ + err_code = SOAP_INVALID_ACTION; + err_str = Soap_Invalid_Action; - /* validate: content-type == text/xml */ - if( !has_xml_content_type( request ) ) { - goto error_handler; - } - /* type of request */ - if( get_request_type( request, &action_name ) != 0 ) { - goto error_handler; - } - /* parse XML */ - err_code = ixmlParseBufferEx( request->entity.buf, &xml_doc ); - if( err_code != IXML_SUCCESS ) { - if( err_code == IXML_INSUFFICIENT_MEMORY ) { - err_code = UPNP_E_OUTOF_MEMORY; - } else { - err_code = SOAP_ACTION_FAILED; - } + /* validate: content-type == text/xml */ + if (!has_xml_content_type(request)) + goto error_handler; + /* type of request */ + if (get_request_type(request, &action_name) != 0) + goto error_handler; + /* parse XML */ + err_code = ixmlParseBufferEx(request->entity.buf, &xml_doc); + if (err_code != IXML_SUCCESS) { + if (err_code == IXML_INSUFFICIENT_MEMORY) + err_code = UPNP_E_OUTOF_MEMORY; + else + err_code = SOAP_ACTION_FAILED; + err_str = "XML error"; + goto error_handler; + } + if (action_name.length == 0) + /* query var */ + handle_query_variable(info, request, xml_doc); + else + /* invoke action */ + handle_invoke_action(info, request, action_name, xml_doc); + /* no error */ + err_code = 0; - err_str = "XML error"; - goto error_handler; - } - - if( action_name.length == 0 ) { - /* query var */ - handle_query_variable( info, request, xml_doc ); - } else { - /* invoke action */ - handle_invoke_action( info, request, action_name, xml_doc ); - } - - err_code = 0; /* no error */ - - error_handler: - ixmlDocument_free( xml_doc ); - if( err_code != 0 ) { - send_error_response( info, err_code, err_str, request ); - } + error_handler: + ixmlDocument_free(xml_doc); + if (err_code != 0) + send_error_response(info, err_code, err_str, request); + return; + parser = parser; } #endif /* EXCLUDE_SOAP */ diff --git a/upnp/src/ssdp/ssdp_ctrlpt.c b/upnp/src/ssdp/ssdp_ctrlpt.c index 80136fc..043d551 100644 --- a/upnp/src/ssdp/ssdp_ctrlpt.c +++ b/upnp/src/ssdp/ssdp_ctrlpt.c @@ -81,7 +81,7 @@ void send_search_result(IN void *data) * SSDP message from the device * IN struct sockaddr *dest_addr: * Address of the device - * IN xboolean timeout: + * IN int timeout: * timeout kept by the control point while * sending search message * IN void* cookie: @@ -101,230 +101,227 @@ void ssdp_handle_ctrlpt_msg( IN http_message_t *hmsg, IN struct sockaddr *dest_addr, /* only in search reply */ - IN xboolean timeout, + IN int timeout, /* only in search reply */ IN void *cookie) { - int handle; - struct Handle_Info *ctrlpt_info = NULL; - memptr hdr_value; - /* byebye or alive */ - xboolean is_byebye; - struct Upnp_Discovery param; - SsdpEvent event; - xboolean nt_found; - xboolean usn_found; - xboolean st_found; - char save_char; - Upnp_EventType event_type; - Upnp_FunPtr ctrlpt_callback; - void *ctrlpt_cookie; - ListNode *node = NULL; - SsdpSearchArg *searchArg = NULL; - int matched = 0; - ResultData *threadData = NULL; - ThreadPoolJob job; + int handle; + struct Handle_Info *ctrlpt_info = NULL; + memptr hdr_value; + /* byebye or alive */ + int is_byebye; + struct Upnp_Discovery param; + SsdpEvent event; + int nt_found; + int usn_found; + int st_found; + char save_char; + Upnp_EventType event_type; + Upnp_FunPtr ctrlpt_callback; + void *ctrlpt_cookie; + ListNode *node = NULL; + SsdpSearchArg *searchArg = NULL; + int matched = 0; + ResultData *threadData = NULL; + ThreadPoolJob job; - /* we are assuming that there can be only one client supported at a time */ - HandleReadLock(); + /* we are assuming that there can be only one client supported at a time */ + HandleReadLock(); - if ( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) { - HandleUnlock(); - return; - } - /* copy */ - ctrlpt_callback = ctrlpt_info->Callback; - ctrlpt_cookie = ctrlpt_info->Cookie; - HandleUnlock(); - /* search timeout */ - if ( timeout ) { - ctrlpt_callback( UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie ); - return; - } - param.ErrCode = UPNP_E_SUCCESS; - /* MAX-AGE, assume error */ - param.Expires = -1; - if ( httpmsg_find_hdr( hmsg, HDR_CACHE_CONTROL, &hdr_value ) != NULL ) { - if( matchstr( hdr_value.buf, hdr_value.length, - "%imax-age = %d%0", ¶m.Expires ) != PARSE_OK ) - return; - } - /* DATE */ - param.Date[0] = '\0'; - if ( httpmsg_find_hdr( hmsg, HDR_DATE, &hdr_value ) != NULL ) { - linecopylen( param.Date, hdr_value.buf, hdr_value.length ); - } - /* dest addr */ - memcpy(¶m.DestAddr, dest_addr, sizeof(struct sockaddr_in) ); - /* EXT */ - param.Ext[0] = '\0'; - if ( httpmsg_find_hdr( hmsg, HDR_EXT, &hdr_value ) != NULL ) { - linecopylen( param.Ext, hdr_value.buf, hdr_value.length ); - } - /* LOCATION */ - param.Location[0] = '\0'; - if ( httpmsg_find_hdr( hmsg, HDR_LOCATION, &hdr_value ) != NULL ) { - linecopylen( param.Location, hdr_value.buf, hdr_value.length ); - } - /* SERVER / USER-AGENT */ - param.Os[0] = '\0'; - if ( httpmsg_find_hdr( hmsg, HDR_SERVER, &hdr_value ) != NULL || - httpmsg_find_hdr( hmsg, HDR_USER_AGENT, &hdr_value ) != NULL ) { - linecopylen( param.Os, hdr_value.buf, hdr_value.length ); - } - /* clear everything */ - param.DeviceId[0] = '\0'; - param.DeviceType[0] = '\0'; - param.ServiceType[0] = '\0'; - /* not used; version is in ServiceType */ - param.ServiceVer[0] = '\0'; + if (GetClientHandleInfo(&handle, &ctrlpt_info) != HND_CLIENT) { + HandleUnlock(); + return; + } + /* copy */ + ctrlpt_callback = ctrlpt_info->Callback; + ctrlpt_cookie = ctrlpt_info->Cookie; + HandleUnlock(); + /* search timeout */ + if (timeout) { + ctrlpt_callback(UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie); + return; + } + param.ErrCode = UPNP_E_SUCCESS; + /* MAX-AGE, assume error */ + param.Expires = -1; + if (httpmsg_find_hdr(hmsg, HDR_CACHE_CONTROL, &hdr_value) != NULL) { + if (matchstr(hdr_value.buf, hdr_value.length, + "%imax-age = %d%0", ¶m.Expires) != PARSE_OK) + return; + } + /* DATE */ + param.Date[0] = '\0'; + if (httpmsg_find_hdr(hmsg, HDR_DATE, &hdr_value) != NULL) { + linecopylen(param.Date, hdr_value.buf, hdr_value.length); + } + /* dest addr */ + memcpy(¶m.DestAddr, dest_addr, sizeof(struct sockaddr_in)); + /* EXT */ + param.Ext[0] = '\0'; + if (httpmsg_find_hdr(hmsg, HDR_EXT, &hdr_value) != NULL) { + linecopylen(param.Ext, hdr_value.buf, hdr_value.length); + } + /* LOCATION */ + param.Location[0] = '\0'; + if (httpmsg_find_hdr(hmsg, HDR_LOCATION, &hdr_value) != NULL) { + linecopylen(param.Location, hdr_value.buf, hdr_value.length); + } + /* SERVER / USER-AGENT */ + param.Os[0] = '\0'; + if (httpmsg_find_hdr(hmsg, HDR_SERVER, &hdr_value) != NULL || + httpmsg_find_hdr(hmsg, HDR_USER_AGENT, &hdr_value) != NULL) { + linecopylen(param.Os, hdr_value.buf, hdr_value.length); + } + /* clear everything */ + param.DeviceId[0] = '\0'; + param.DeviceType[0] = '\0'; + param.ServiceType[0] = '\0'; + /* not used; version is in ServiceType */ + param.ServiceVer[0] = '\0'; + event.UDN[0] = '\0'; + event.DeviceType[0] = '\0'; + event.ServiceType[0] = '\0'; + nt_found = FALSE; + if (httpmsg_find_hdr(hmsg, HDR_NT, &hdr_value) != NULL) { + save_char = hdr_value.buf[hdr_value.length]; + hdr_value.buf[hdr_value.length] = '\0'; + nt_found = (ssdp_request_type(hdr_value.buf, &event) == 0); + hdr_value.buf[hdr_value.length] = save_char; + } + usn_found = FALSE; + if (httpmsg_find_hdr(hmsg, HDR_USN, &hdr_value) != NULL) { + save_char = hdr_value.buf[hdr_value.length]; + hdr_value.buf[hdr_value.length] = '\0'; + usn_found = (unique_service_name(hdr_value.buf, &event) == 0); + hdr_value.buf[hdr_value.length] = save_char; + } + if (nt_found || usn_found) { + strcpy(param.DeviceId, event.UDN); + strcpy(param.DeviceType, event.DeviceType); + strcpy(param.ServiceType, event.ServiceType); + } + /* ADVERT. OR BYEBYE */ + if (hmsg->is_request) { + /* use NTS hdr to determine advert., or byebye */ + if (httpmsg_find_hdr(hmsg, HDR_NTS, &hdr_value) == NULL) { + return; /* error; NTS header not found */ + } + if (memptr_cmp(&hdr_value, "ssdp:alive") == 0) { + is_byebye = FALSE; + } else if (memptr_cmp(&hdr_value, "ssdp:byebye") == 0) { + is_byebye = TRUE; + } else { + return; /* bad value */ + } + if (is_byebye) { + /* check device byebye */ + if (!nt_found || !usn_found) { + return; /* bad byebye */ + } + event_type = UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE; + } else { + /* check advertisement. + * Expires is valid if positive. This is for testing + * only. Expires should be greater than 1800 (30 mins) */ + if (!nt_found || + !usn_found || + strlen(param.Location) == 0 || param.Expires <= 0) { + return; /* bad advertisement */ + } + event_type = UPNP_DISCOVERY_ADVERTISEMENT_ALIVE; + } + /* call callback */ + ctrlpt_callback(event_type, ¶m, ctrlpt_cookie); + } else { + /* reply (to a SEARCH) */ + /* only checking to see if there is a valid ST header */ + st_found = FALSE; + if (httpmsg_find_hdr(hmsg, HDR_ST, &hdr_value) != NULL) { + save_char = hdr_value.buf[hdr_value.length]; + hdr_value.buf[hdr_value.length] = '\0'; + st_found = + ssdp_request_type(hdr_value.buf, &event) == 0; + hdr_value.buf[hdr_value.length] = save_char; + } + if (hmsg->status_code != HTTP_OK || + param.Expires <= 0 || + strlen(param.Location) == 0 || !usn_found || !st_found) { + return; /* bad reply */ + } + /* check each current search */ + HandleLock(); + if (GetClientHandleInfo(&handle, &ctrlpt_info) != HND_CLIENT) { + HandleUnlock(); + return; + } + node = ListHead(&ctrlpt_info->SsdpSearchList); + /* temporary add null termination */ + /*save_char = hdr_value.buf[ hdr_value.length ]; */ + /*hdr_value.buf[ hdr_value.length ] = '\0'; */ + while (node != NULL) { + searchArg = node->item; + matched = 0; + /* check for match of ST header and search target */ + switch (searchArg->requestType) { + case SSDP_ALL: + matched = 1; + break; + case SSDP_ROOTDEVICE: + matched = + (event.RequestType == SSDP_ROOTDEVICE); + break; + case SSDP_DEVICEUDN: + matched = !strncmp(searchArg->searchTarget, + hdr_value.buf, + hdr_value.length); + break; + case SSDP_DEVICETYPE:{ + size_t m = min(hdr_value.length, + strlen(searchArg-> + searchTarget)); + matched = !strncmp(searchArg->searchTarget, + hdr_value.buf, m); + break; + } + case SSDP_SERVICE:{ + size_t m = min(hdr_value.length, + strlen(searchArg-> + searchTarget)); + matched = !strncmp(searchArg->searchTarget, + hdr_value.buf, m); + break; + } + default: + matched = 0; + break; + } + if (matched) { + /* schedule call back */ + threadData = + (ResultData *) malloc(sizeof(ResultData)); + if (threadData != NULL) { + threadData->param = param; + threadData->cookie = searchArg->cookie; + threadData->ctrlpt_callback = + ctrlpt_callback; + TPJobInit(&job, + (start_routine) + send_search_result, + threadData); + TPJobSetPriority(&job, MED_PRIORITY); + TPJobSetFreeFunction(&job, + (free_routine) + free); + ThreadPoolAdd(&gRecvThreadPool, &job, + NULL); + } + } + node = ListNext(&ctrlpt_info->SsdpSearchList, node); + } - event.UDN[0] = '\0'; - event.DeviceType[0] = '\0'; - event.ServiceType[0] = '\0'; - - nt_found = FALSE; - - if ( httpmsg_find_hdr( hmsg, HDR_NT, &hdr_value ) != NULL ) { - save_char = hdr_value.buf[hdr_value.length]; - hdr_value.buf[hdr_value.length] = '\0'; - nt_found = ( ssdp_request_type( hdr_value.buf, &event ) == 0 ); - hdr_value.buf[hdr_value.length] = save_char; - } - - usn_found = FALSE; - if ( httpmsg_find_hdr( hmsg, HDR_USN, &hdr_value ) != NULL ) { - save_char = hdr_value.buf[hdr_value.length]; - hdr_value.buf[hdr_value.length] = '\0'; - usn_found = ( unique_service_name( hdr_value.buf, &event ) == 0 ); - hdr_value.buf[hdr_value.length] = save_char; - } - - if ( nt_found || usn_found ) { - strcpy( param.DeviceId, event.UDN ); - strcpy( param.DeviceType, event.DeviceType ); - strcpy( param.ServiceType, event.ServiceType ); - } - - /* ADVERT. OR BYEBYE */ - if( hmsg->is_request ) { - /* use NTS hdr to determine advert., or byebye */ - if ( httpmsg_find_hdr( hmsg, HDR_NTS, &hdr_value ) == NULL ) { - return; /* error; NTS header not found */ - } - if ( memptr_cmp( &hdr_value, "ssdp:alive" ) == 0 ) { - is_byebye = FALSE; - } else if( memptr_cmp( &hdr_value, "ssdp:byebye" ) == 0 ) { - is_byebye = TRUE; - } else { - return; /* bad value */ - } - - if ( is_byebye ) { - /* check device byebye */ - if( !nt_found || !usn_found ) { - return; /* bad byebye */ - } - event_type = UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE; - } else { - /* check advertisement. - * Expires is valid if positive. This is for testing - * only. Expires should be greater than 1800 (30 mins) */ - if( !nt_found || - !usn_found || - strlen( param.Location ) == 0 || param.Expires <= 0 ) { - return; /* bad advertisement */ - } - event_type = UPNP_DISCOVERY_ADVERTISEMENT_ALIVE; - } - - /* call callback */ - ctrlpt_callback( event_type, ¶m, ctrlpt_cookie ); - - } else { - /* reply (to a SEARCH) */ - /* only checking to see if there is a valid ST header */ - st_found = FALSE; - if( httpmsg_find_hdr( hmsg, HDR_ST, &hdr_value ) != NULL ) { - save_char = hdr_value.buf[hdr_value.length]; - hdr_value.buf[hdr_value.length] = '\0'; - st_found = ssdp_request_type( hdr_value.buf, &event ) == 0; - hdr_value.buf[hdr_value.length] = save_char; - } - if( hmsg->status_code != HTTP_OK || - param.Expires <= 0 || - strlen( param.Location ) == 0 || !usn_found || !st_found ) { - return; /* bad reply */ - } - /* check each current search */ - HandleLock(); - if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) { - HandleUnlock(); - return; - } - node = ListHead( &ctrlpt_info->SsdpSearchList ); - - /* temporary add null termination */ - /*save_char = hdr_value.buf[ hdr_value.length ]; */ - /*hdr_value.buf[ hdr_value.length ] = '\0'; */ - - while( node != NULL ) { - searchArg = node->item; - matched = 0; - /* check for match of ST header and search target */ - switch ( searchArg->requestType ) { - case SSDP_ALL: - matched = 1; - break; - case SSDP_ROOTDEVICE: - matched = ( event.RequestType == SSDP_ROOTDEVICE ); - break; - case SSDP_DEVICEUDN: - matched = !( strncmp( searchArg->searchTarget, - hdr_value.buf, - hdr_value.length ) ); - break; - case SSDP_DEVICETYPE: { - int m = min( hdr_value.length, - strlen( searchArg->searchTarget ) ); - matched = !( strncmp( searchArg->searchTarget, - hdr_value.buf, m ) ); - break; - } - case SSDP_SERVICE: { - int m = min( hdr_value.length, - strlen( searchArg->searchTarget ) ); - - matched = !( strncmp( searchArg->searchTarget, - hdr_value.buf, m ) ); - break; - } - default: - matched = 0; - break; - } - - if (matched) { - /* schedule call back*/ - threadData = - ( ResultData * ) malloc( sizeof( ResultData ) ); - if (threadData != NULL) { - threadData->param = param; - threadData->cookie = searchArg->cookie; - threadData->ctrlpt_callback = ctrlpt_callback; - TPJobInit( &job, ( start_routine ) send_search_result, - threadData ); - TPJobSetPriority(&job, MED_PRIORITY); - TPJobSetFreeFunction(&job, (free_routine)free); - ThreadPoolAdd(&gRecvThreadPool, &job, NULL); - } - } - node = ListNext( &ctrlpt_info->SsdpSearchList, node ); - } - - HandleUnlock(); - /*ctrlpt_callback( UPNP_DISCOVERY_SEARCH_RESULT, ¶m, cookie );*/ - } + HandleUnlock(); + /*ctrlpt_callback( UPNP_DISCOVERY_SEARCH_RESULT, ¶m, cookie ); */ + } } diff --git a/upnp/src/ssdp/ssdp_device.c b/upnp/src/ssdp/ssdp_device.c index a8cca2c..202623a 100644 --- a/upnp/src/ssdp/ssdp_device.c +++ b/upnp/src/ssdp/ssdp_device.c @@ -217,78 +217,75 @@ void ssdp_handle_device_request( * Returns: void * * 1 if successful else appropriate error ***************************************************************************/ -static int -NewRequestHandler( IN struct sockaddr *DestAddr, - IN int NumPacket, - IN char **RqPacket ) +static int NewRequestHandler(IN struct sockaddr *DestAddr, IN int NumPacket, + IN char **RqPacket) { - char errorBuffer[ERROR_BUFFER_LEN]; - SOCKET ReplySock; - int socklen = sizeof( struct sockaddr_storage ); - int Index; - unsigned long replyAddr = inet_addr( gIF_IPV4 ); - /* a/c to UPNP Spec */ - int ttl = 4; - int hops = 1; - char buf_ntop[64]; - int ret = UPNP_E_SUCCESS; + char errorBuffer[ERROR_BUFFER_LEN]; + SOCKET ReplySock; + socklen_t socklen = sizeof(struct sockaddr_storage); + int Index; + unsigned long replyAddr = inet_addr(gIF_IPV4); + /* a/c to UPNP Spec */ + int ttl = 4; + int hops = 1; + char buf_ntop[64]; + int ret = UPNP_E_SUCCESS; - ReplySock = socket( DestAddr->sa_family, SOCK_DGRAM, 0 ); - if ( ReplySock == -1 ) { - strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN); - UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__, - "SSDP_LIB: New Request Handler:" - "Error in socket(): %s\n", errorBuffer ); + ReplySock = socket(DestAddr->sa_family, SOCK_DGRAM, 0); + if (ReplySock == -1) { + strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN); + UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, + "SSDP_LIB: New Request Handler:" + "Error in socket(): %s\n", errorBuffer); - return UPNP_E_OUTOF_SOCKET; - } - - if( DestAddr->sa_family == AF_INET ) { - inet_ntop(AF_INET, &((struct sockaddr_in*)DestAddr)->sin_addr, - buf_ntop, sizeof(buf_ntop)); - setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_IF, - (char *)&replyAddr, sizeof (replyAddr) ); - setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_TTL, - (char *)&ttl, sizeof (int) ); - socklen = sizeof(struct sockaddr_in); - } else if( DestAddr->sa_family == AF_INET6 ) { - inet_ntop(AF_INET6, &((struct sockaddr_in6*)DestAddr)->sin6_addr, - buf_ntop, sizeof(buf_ntop)); - setsockopt( ReplySock, IPPROTO_IPV6, IPV6_MULTICAST_IF, - (char *)&gIF_INDEX, sizeof(gIF_INDEX) ); - setsockopt( ReplySock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, - (char *)&hops, sizeof(hops) ); - } else { - UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__, - "Invalid destination address specified." ); - ret = UPNP_E_NETWORK_ERROR; - goto end_NewRequestHandler; - } + return UPNP_E_OUTOF_SOCKET; + } - for( Index = 0; Index < NumPacket; Index++ ) { - int rc; - UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__, - ">>> SSDP SEND to %s >>>\n%s\n", - buf_ntop, *( RqPacket + Index ) ); - rc = sendto( ReplySock, *( RqPacket + Index ), - strlen( *( RqPacket + Index ) ), - 0, DestAddr, socklen ); + if (DestAddr->sa_family == AF_INET) { + inet_ntop(AF_INET, &((struct sockaddr_in *)DestAddr)->sin_addr, + buf_ntop, sizeof(buf_ntop)); + setsockopt(ReplySock, IPPROTO_IP, IP_MULTICAST_IF, + (char *)&replyAddr, sizeof(replyAddr)); + setsockopt(ReplySock, IPPROTO_IP, IP_MULTICAST_TTL, + (char *)&ttl, sizeof(int)); + socklen = sizeof(struct sockaddr_in); + } else if (DestAddr->sa_family == AF_INET6) { + inet_ntop(AF_INET6, + &((struct sockaddr_in6 *)DestAddr)->sin6_addr, + buf_ntop, sizeof(buf_ntop)); + setsockopt(ReplySock, IPPROTO_IPV6, IPV6_MULTICAST_IF, + (char *)&gIF_INDEX, sizeof(gIF_INDEX)); + setsockopt(ReplySock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, + (char *)&hops, sizeof(hops)); + } else { + UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__, + "Invalid destination address specified."); + ret = UPNP_E_NETWORK_ERROR; + goto end_NewRequestHandler; + } - if (rc == -1) { - strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN); - UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__, - "SSDP_LIB: New Request Handler:" - "Error in socket(): %s\n", errorBuffer ); - ret = UPNP_E_SOCKET_WRITE; - goto end_NewRequestHandler; - } - } + for (Index = 0; Index < NumPacket; Index++) { + ssize_t rc; + UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, + ">>> SSDP SEND to %s >>>\n%s\n", + buf_ntop, *(RqPacket + Index)); + rc = sendto(ReplySock, *(RqPacket + Index), + strlen(*(RqPacket + Index)), 0, DestAddr, socklen); + if (rc == -1) { + strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN); + UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, + "SSDP_LIB: New Request Handler:" + "Error in socket(): %s\n", errorBuffer); + ret = UPNP_E_SOCKET_WRITE; + goto end_NewRequestHandler; + } + } -end_NewRequestHandler: - shutdown( ReplySock, SD_BOTH ); - UpnpCloseSocket( ReplySock ); + end_NewRequestHandler: + shutdown(ReplySock, SD_BOTH); + UpnpCloseSocket(ReplySock); - return ret; + return ret; } /** @@ -367,9 +364,9 @@ int isUrlV6UlaGua(char *descdocUrl) * Returns: void * ***************************************************************************/ -void CreateServicePacket( +static void CreateServicePacket( IN int msg_type, - IN char *nt, + const IN char *nt, IN char *usn, IN char *location, IN int duration, @@ -377,7 +374,7 @@ void CreateServicePacket( IN int AddressFamily) { int ret_code; - char *nts; + const char *nts; membuffer buf; /* Notf == 0 means service shutdown, @@ -405,23 +402,22 @@ void CreateServicePacket( } } else if (msg_type == MSGTYPE_ADVERTISEMENT || msg_type == MSGTYPE_SHUTDOWN) { - char *host = NULL; - if (msg_type == MSGTYPE_ADVERTISEMENT) { + const char *host = NULL; + + if (msg_type == MSGTYPE_ADVERTISEMENT) nts = "ssdp:alive"; - } else { + else /* shutdown */ nts = "ssdp:byebye"; - } /* NOTE: The CACHE-CONTROL and LOCATION headers are not present in * a shutdown msg, but are present here for MS WinMe interop. */ - if (AddressFamily == AF_INET) { + if (AddressFamily == AF_INET) host = SSDP_IP; - } else { - if (isUrlV6UlaGua(location)) { + else { + if (isUrlV6UlaGua(location)) host = "[" SSDP_IPV6_SITELOCAL "]"; - } else { + else host = "[" SSDP_IPV6_LINKLOCAL "]"; - } } ret_code = http_MakeMessage( &buf, 1, 1, @@ -437,14 +433,11 @@ void CreateServicePacket( "NTS: ", nts, X_USER_AGENT, "USN: ", usn ); - if (ret_code != 0) { + if (ret_code) return; - } - } else { + } else /* unknown msg */ assert(0); - } - /* return msg */ *packet = membuffer_detach(&buf); membuffer_destroy(&buf); @@ -959,6 +952,7 @@ DeviceShutdown( IN char *DevType, free( msgs[2] ); return ret_code; + _Server = _Server; } #endif /* EXCLUDE_SSDP */ diff --git a/upnp/src/ssdp/ssdp_server.c b/upnp/src/ssdp/ssdp_server.c index abc2d6d..c10167d 100644 --- a/upnp/src/ssdp/ssdp_server.c +++ b/upnp/src/ssdp/ssdp_server.c @@ -120,8 +120,8 @@ int AdvertiseAndReply( int Exp) { int retVal = UPNP_E_SUCCESS; - int i; - int j; + long unsigned int i; + long unsigned int j; int defaultExp = DEFAULT_MAXAGE; struct Handle_Info *SInfo = NULL; char UDNstr[100]; @@ -461,87 +461,73 @@ Make_Socket_NoBlocking( SOCKET sock ) ***************************************************************************/ int unique_service_name(IN char *cmd, IN SsdpEvent *Evt) { - char TempBuf[COMMAND_LEN]; - char *TempPtr = NULL; - char *Ptr = NULL; - char *ptr1 = NULL; - char *ptr2 = NULL; - char *ptr3 = NULL; - int CommandFound = 0; - int length = 0; + char TempBuf[COMMAND_LEN]; + char *TempPtr = NULL; + char *Ptr = NULL; + char *ptr1 = NULL; + char *ptr2 = NULL; + char *ptr3 = NULL; + int CommandFound = 0; + size_t n = 0; - if( ( TempPtr = strstr( cmd, "uuid:schemas" ) ) != NULL ) { - ptr1 = strstr( cmd, ":device" ); - if( ptr1 != NULL ) { - ptr2 = strstr( ptr1 + 1, ":" ); - } else { - return -1; - } + if ((TempPtr = strstr(cmd, "uuid:schemas")) != NULL) { + ptr1 = strstr(cmd, ":device"); + if (ptr1 != NULL) + ptr2 = strstr(ptr1 + 1, ":"); + else + return -1; + if (ptr2 != NULL) + ptr3 = strstr(ptr2 + 1, ":"); + else + return -1; + if (ptr3 != NULL) + sprintf(Evt->UDN, "uuid:%s", ptr3 + 1); + else + return -1; + ptr1 = strstr(cmd, ":"); + if (ptr1 != NULL) { + n = (size_t)(ptr3 - ptr1); + strncpy(TempBuf, ptr1, n); + TempBuf[n] = '\0'; + sprintf(Evt->DeviceType, "urn%s", TempBuf); + } else + return -1; + return 0; + } + if ((TempPtr = strstr(cmd, "uuid")) != NULL) { + if ((Ptr = strstr(cmd, "::")) != NULL) { + n = (size_t)(Ptr - TempPtr); + strncpy(Evt->UDN, TempPtr, n); + Evt->UDN[n] = '\0'; + } else + strcpy(Evt->UDN, TempPtr); + CommandFound = 1; + } + if (strstr(cmd, "urn:") != NULL && strstr(cmd, ":service:") != NULL) { + if ((TempPtr = strstr(cmd, "urn")) != NULL) { + strcpy(Evt->ServiceType, TempPtr); + CommandFound = 1; + } + } + if (strstr(cmd, "urn:") != NULL && strstr(cmd, ":device:") != NULL) { + if ((TempPtr = strstr(cmd, "urn")) != NULL) { + strcpy(Evt->DeviceType, TempPtr); + CommandFound = 1; + } + } + if ((TempPtr = strstr(cmd, "::upnp:rootdevice")) != NULL) { + /* Everything before "::upnp::rootdevice" is the UDN. */ + if (TempPtr != cmd) { + n = (size_t)(TempPtr - cmd); + strncpy(Evt->UDN, cmd, n); + Evt->UDN[n] = 0; + CommandFound = 1; + } + } + if (CommandFound == 0) + return -1; - if( ptr2 != NULL ) { - ptr3 = strstr( ptr2 + 1, ":" ); - } else { - return -1; - } - - if( ptr3 != NULL ) { - sprintf( Evt->UDN, "uuid:%s", ptr3 + 1 ); - } else { - return -1; - } - - ptr1 = strstr( cmd, ":" ); - if( ptr1 != NULL ) { - strncpy( TempBuf, ptr1, ptr3 - ptr1 ); - TempBuf[ptr3 - ptr1] = '\0'; - sprintf( Evt->DeviceType, "urn%s", TempBuf ); - } else { - return -1; - } - return 0; - } - - if( ( TempPtr = strstr( cmd, "uuid" ) ) != NULL ) { - if( ( Ptr = strstr( cmd, "::" ) ) != NULL ) { - strncpy( Evt->UDN, TempPtr, Ptr - TempPtr ); - Evt->UDN[Ptr - TempPtr] = '\0'; - } else { - strcpy( Evt->UDN, TempPtr ); - } - CommandFound = 1; - } - - if( strstr( cmd, "urn:" ) != NULL - && strstr( cmd, ":service:" ) != NULL ) { - if( ( TempPtr = strstr( cmd, "urn" ) ) != NULL ) { - strcpy( Evt->ServiceType, TempPtr ); - CommandFound = 1; - } - } - - if( strstr( cmd, "urn:" ) != NULL - && strstr( cmd, ":device:" ) != NULL ) { - if( ( TempPtr = strstr( cmd, "urn" ) ) != NULL ) { - strcpy( Evt->DeviceType, TempPtr ); - CommandFound = 1; - } - } - - if( ( TempPtr = strstr( cmd, "::upnp:rootdevice" ) ) != NULL ) { - /* Everything before "::upnp::rootdevice" is the UDN. */ - if( TempPtr != cmd ) { - length = TempPtr - cmd; - strncpy(Evt->UDN, cmd, length); - Evt->UDN[length] = 0; - CommandFound = 1; - } - } - - if( CommandFound == 0 ) { - return -1; - } - - return 0; + return 0; } /************************************************************************ @@ -779,102 +765,85 @@ static void ssdp_event_handler_thread(void *the_data) * Returns: void * ***************************************************************************/ -void -readFromSSDPSocket( SOCKET socket ) +void readFromSSDPSocket(SOCKET socket) { - char *requestBuf = NULL; - char staticBuf[BUFSIZE]; - struct sockaddr_storage __ss; - ThreadPoolJob job; - ssdp_thread_data *data = NULL; - socklen_t socklen = sizeof( __ss ); - int byteReceived = 0; - char ntop_buf[64]; + char *requestBuf = NULL; + char staticBuf[BUFSIZE]; + struct sockaddr_storage __ss; + ThreadPoolJob job; + ssdp_thread_data *data = NULL; + socklen_t socklen = sizeof(__ss); + ssize_t byteReceived = 0; + char ntop_buf[64]; - requestBuf = staticBuf; - - /* in case memory can't be allocated, still drain the socket using a - * static buffer. */ - data = ( ssdp_thread_data * ) - malloc( sizeof( ssdp_thread_data ) ); - - if( data != NULL ) { - /* initialize parser */ + requestBuf = staticBuf; + /* in case memory can't be allocated, still drain the socket using a + * static buffer. */ + data = malloc(sizeof(ssdp_thread_data)); + if (data) { + /* initialize parser */ #ifdef INCLUDE_CLIENT_APIS #ifdef UPNP_ENABLE_IPV6 - if( socket == gSsdpReqSocket4 || socket == gSsdpReqSocket6 ) { - parser_response_init( &data->parser, HTTPMETHOD_MSEARCH ); - } else { - parser_request_init( &data->parser ); - } -#else - if( socket == gSsdpReqSocket4 ) { - parser_response_init( &data->parser, HTTPMETHOD_MSEARCH ); - } else { - parser_request_init( &data->parser ); - } - -#endif -#else - parser_request_init( &data->parser ); -#endif - /* set size of parser buffer */ - if( membuffer_set_size( &data->parser.msg.msg, BUFSIZE ) == 0 ) { - /* use this as the buffer for recv */ - requestBuf = data->parser.msg.msg.buf; - - } else { - free( data ); - data = NULL; - } - } - byteReceived = recvfrom( socket, requestBuf, - BUFSIZE - 1, 0, - (struct sockaddr *)&__ss, &socklen ); - - if( byteReceived > 0 ) { - requestBuf[byteReceived] = '\0'; - - if( __ss.ss_family == AF_INET ) - inet_ntop( AF_INET, &((struct sockaddr_in*)&__ss)->sin_addr, ntop_buf, sizeof(ntop_buf) ); + if (socket == gSsdpReqSocket4 || socket == gSsdpReqSocket6) + parser_response_init(&data->parser, HTTPMETHOD_MSEARCH); + else + parser_request_init(&data->parser); +#else /* UPNP_ENABLE_IPV6 */ + if (socket == gSsdpReqSocket4) + parser_response_init(&data->parser, HTTPMETHOD_MSEARCH); + else + parser_request_init(&data->parser); +#endif /* UPNP_ENABLE_IPV6 */ +#else /* INCLUDE_CLIENT_APIS */ + parser_request_init(&data->parser); +#endif /* INCLUDE_CLIENT_APIS */ + /* set size of parser buffer */ + if (membuffer_set_size(&data->parser.msg.msg, BUFSIZE) == 0) + /* use this as the buffer for recv */ + requestBuf = data->parser.msg.msg.buf; + else { + free(data); + data = NULL; + } + } + byteReceived = recvfrom(socket, requestBuf, BUFSIZE - 1, 0, + (struct sockaddr *)&__ss, &socklen); + if (byteReceived > 0) { + requestBuf[byteReceived] = '\0'; + if (__ss.ss_family == AF_INET) + inet_ntop(AF_INET, + &((struct sockaddr_in *)&__ss)->sin_addr, + ntop_buf, sizeof(ntop_buf)); #ifdef UPNP_ENABLE_IPV6 - else if( __ss.ss_family == AF_INET6 ) - inet_ntop( AF_INET6, &((struct sockaddr_in6*)&__ss)->sin6_addr, ntop_buf, sizeof(ntop_buf) ); + else if (__ss.ss_family == AF_INET6) + inet_ntop(AF_INET6, + &((struct sockaddr_in6 *)&__ss)->sin6_addr, + ntop_buf, sizeof(ntop_buf)); #endif - else - strncpy( ntop_buf, "", sizeof(ntop_buf) ); - - UpnpPrintf( UPNP_INFO, SSDP, - __FILE__, __LINE__, - "Start of received response ----------------------------------------------------\n" - "%s\n" - "End of received response ------------------------------------------------------\n" - "From host %s\n", - requestBuf, - ntop_buf ); - UpnpPrintf( UPNP_PACKET, SSDP, __FILE__, __LINE__, - "Start of received multicast packet --------------------------------------------\n" - "%s\n" - "End of received multicast packet ----------------------------------------------\n", - requestBuf ); - /* add thread pool job to handle request */ - if( data != NULL ) { - data->parser.msg.msg.length += byteReceived; - /* null-terminate */ - data->parser.msg.msg.buf[byteReceived] = 0; - memcpy( &data->dest_addr, &__ss, sizeof(__ss) ); - TPJobInit( &job, ( start_routine ) - ssdp_event_handler_thread, data ); - TPJobSetFreeFunction( &job, free_ssdp_event_handler_data ); - TPJobSetPriority( &job, MED_PRIORITY ); - - if( ThreadPoolAdd( &gRecvThreadPool, &job, NULL ) != 0 ) { - free_ssdp_event_handler_data( data ); - } - } - } else { - free_ssdp_event_handler_data( data ); - } + else + strncpy(ntop_buf, "", + sizeof(ntop_buf)); + UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, + "Start of received response ----------------------------------------------------\n" + "%s\n" + "End of received response ------------------------------------------------------\n" + "From host %s\n", requestBuf, ntop_buf); + /* add thread pool job to handle request */ + if (data != NULL) { + data->parser.msg.msg.length += (size_t)byteReceived; + /* null-terminate */ + data->parser.msg.msg.buf[byteReceived] = 0; + memcpy(&data->dest_addr, &__ss, sizeof(__ss)); + TPJobInit(&job, (start_routine) + ssdp_event_handler_thread, data); + TPJobSetFreeFunction(&job, + free_ssdp_event_handler_data); + TPJobSetPriority(&job, MED_PRIORITY); + if (ThreadPoolAdd(&gRecvThreadPool, &job, NULL) != 0) + free_ssdp_event_handler_data(data); + } + } else + free_ssdp_event_handler_data(data); } @@ -907,10 +876,8 @@ int get_ssdp_sockets(MiniServerSockArray *out) } /* For use by ssdp control point. */ gSsdpReqSocket4 = out->ssdpReqSock4; - } else { + } else out->ssdpReqSock4 = INVALID_SOCKET; - } - /* Create the IPv6 socket for SSDP REQUESTS */ #ifdef UPNP_ENABLE_IPV6 if (strlen(gIF_IPV6) > 0) { @@ -922,14 +889,10 @@ int get_ssdp_sockets(MiniServerSockArray *out) } /* For use by ssdp control point. */ gSsdpReqSocket6 = out->ssdpReqSock6; - } else { + } else out->ssdpReqSock6 = INVALID_SOCKET; - } #endif /* IPv6 */ - - #endif /* INCLUDE_CLIENT_APIS */ - /* Create the IPv4 socket for SSDP */ if (strlen(gIF_IPV4) > 0) { retVal = create_ssdp_sock_v4(&out->ssdpSock4); @@ -942,10 +905,8 @@ int get_ssdp_sockets(MiniServerSockArray *out) #endif return retVal; } - } else { + } else out->ssdpSock4 = INVALID_SOCKET; - } - /* Create the IPv6 socket for SSDP */ #ifdef UPNP_ENABLE_IPV6 if (strlen(gIF_IPV6) > 0) { @@ -961,10 +922,8 @@ int get_ssdp_sockets(MiniServerSockArray *out) #endif return retVal; } - } else { + } else out->ssdpSock6 = INVALID_SOCKET; - } - if (strlen(gIF_IPV6_ULA_GUA) > 0) { retVal = create_ssdp_sock_v6_ula_gua(&out->ssdpSock6UlaGua); if (retVal != UPNP_E_SUCCESS) { @@ -980,9 +939,8 @@ int get_ssdp_sockets(MiniServerSockArray *out) #endif return retVal; } - } else { + } else out->ssdpSock6UlaGua = INVALID_SOCKET; - } #endif /* IPv6 */ return UPNP_E_SUCCESS; @@ -1003,26 +961,24 @@ int get_ssdp_sockets(MiniServerSockArray *out) * Returns: * UPNP_E_SUCCESS on successful socket creation. ***************************************************************************/ -int create_ssdp_sock_reqv4( SOCKET* ssdpReqSock ) +int create_ssdp_sock_reqv4(SOCKET *ssdpReqSock) { - char errorBuffer[ERROR_BUFFER_LEN]; - u_char ttl = 4; + char errorBuffer[ERROR_BUFFER_LEN]; + u_char ttl = 4; - *ssdpReqSock = socket( AF_INET, SOCK_DGRAM, 0 ); - if ( *ssdpReqSock == -1 ) { - strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN); - UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__, - "Error in socket(): %s\n", errorBuffer ); - return UPNP_E_OUTOF_SOCKET; - } + *ssdpReqSock = socket(AF_INET, SOCK_DGRAM, 0); + if (*ssdpReqSock == -1) { + strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN); + UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__, + "Error in socket(): %s\n", errorBuffer); + return UPNP_E_OUTOF_SOCKET; + } + setsockopt(*ssdpReqSock, IPPROTO_IP, IP_MULTICAST_TTL, + &ttl, sizeof(ttl)); + /* just do it, regardless if fails or not. */ + Make_Socket_NoBlocking(*ssdpReqSock); - setsockopt( *ssdpReqSock, IPPROTO_IP, IP_MULTICAST_TTL, - &ttl, sizeof (ttl) ); - - /* just do it, regardless if fails or not. */ - Make_Socket_NoBlocking( *ssdpReqSock ); - - return UPNP_E_SUCCESS; + return UPNP_E_SUCCESS; }