/*================================================================ * NamedNodeMap_addToNamedNodeMap * add a node to a NamedNodeMap. * Internal to parser only. * Parameters: * add: the node to add into NamedNodeMap. * Return: * IXML_SUCCESS or failure. * *=================================================================*/ int ixmlNamedNodeMap_addToNamedNodeMap( IN IXML_NamedNodeMap ** nnMap, IN IXML_Node * add ) { IXML_NamedNodeMap *traverse = NULL, *p = NULL; IXML_NamedNodeMap *newItem = NULL; if( add == NULL ) { return IXML_SUCCESS; } if( *nnMap == NULL ) // nodelist is empty { *nnMap = #ifdef _UPNP_MM_ ( IXML_NamedNodeMap * ) upnp_malloc( sizeof( IXML_NamedNodeMap ) ); #else ( IXML_NamedNodeMap * ) malloc( sizeof( IXML_NamedNodeMap ) ); #endif if( *nnMap == NULL ) { return IXML_INSUFFICIENT_MEMORY; } ixmlNamedNodeMap_init( *nnMap ); } if( ( *nnMap )->nodeItem == NULL ) { ( *nnMap )->nodeItem = add; } else { traverse = *nnMap; p = traverse; while( traverse != NULL ) { p = traverse; traverse = traverse->next; } newItem = #ifdef _UPNP_MM_ ( IXML_NamedNodeMap * ) upnp_malloc( sizeof( IXML_NamedNodeMap ) ); #else ( IXML_NamedNodeMap * ) malloc( sizeof( IXML_NamedNodeMap ) ); #endif if( newItem == NULL ) { return IXML_INSUFFICIENT_MEMORY; } p->next = newItem; newItem->nodeItem = add; newItem->next = NULL; } return IXML_SUCCESS; }
/************************************************************************ * Function : copy_URL_list * * Parameters : * URL_list *in ; Source URL list * URL_list *out ; Destination URL list * * Description : Copies one URL_list into another. This includes * dynamically allocating the out->URLs field (the full string), * and the structures used to hold the parsedURLs. This memory MUST * be freed by the caller through: free_URL_list(&out) * * Return : int ; * HTTP_SUCCESS - On Success * UPNP_E_OUTOF_MEMORY - On Failure to allocate memory * * Note : ************************************************************************/ int copy_URL_list( URL_list * in, URL_list * out ) { int len = strlen( in->URLs ) + 1; int i = 0; out->URLs = NULL; out->parsedURLs = NULL; out->size = 0; #ifdef _UPNP_MM_ out->URLs = ( char * )upnp_malloc( len ); out->parsedURLs = ( uri_type * ) upnp_malloc( sizeof( uri_type ) * in->size ); #else out->URLs = ( char * )malloc( len ); out->parsedURLs = ( uri_type * ) malloc( sizeof( uri_type ) * in->size ); #endif if( ( out->URLs == NULL ) || ( out->parsedURLs == NULL ) ) return UPNP_E_OUTOF_MEMORY; memcpy( out->URLs, in->URLs, len ); for( i = 0; i < in->size; i++ ) { //copy the parsed uri out->parsedURLs[i].type = in->parsedURLs[i].type; copy_token( &in->parsedURLs[i].scheme, in->URLs, &out->parsedURLs[i].scheme, out->URLs ); out->parsedURLs[i].path_type = in->parsedURLs[i].path_type; copy_token( &in->parsedURLs[i].pathquery, in->URLs, &out->parsedURLs[i].pathquery, out->URLs ); copy_token( &in->parsedURLs[i].fragment, in->URLs, &out->parsedURLs[i].fragment, out->URLs ); copy_token( &in->parsedURLs[i].hostport.text, in->URLs, &out->parsedURLs[i].hostport.text, out->URLs ); copy_sockaddr_in( &in->parsedURLs[i].hostport.IPv4address, &out->parsedURLs[i].hostport.IPv4address ); } out->size = in->size; return HTTP_SUCCESS; }
// allocate static void * al() { int size, i; void * retptr = NULL; TotalAlloc ++; size = (random() % MAX_ALLOCATE_SIZE); TotalAllocSize += size; retptr = (void *)upnp_malloc(size); if (!retptr) { printf("allocate Warning: out of memory (size : %d)\n", size); upnp_mm_dump(); NullAlloc ++; } return retptr; }
/**************************************************************************** * Function: FreeListAlloc * * Description: * Allocates chunk of set size. * If a free item is available in the list, returnes the stored item. * Otherwise calls the O.S. to allocate memory. * Parameters: * free_list - must be valid, non null, pointer to a linked list. * Returns: * Non NULL on success. NULL on failure. *****************************************************************************/ void * FreeListAlloc( FreeList * free_list ) { FreeListNode *ret = NULL; assert( free_list != NULL ); if( free_list == NULL ) return NULL; if( free_list->head ) { ret = free_list->head; free_list->head = free_list->head->next; free_list->freeListLength--; } else { #ifdef _UPNP_MM_ ret = upnp_malloc( free_list->element_size ); #else ret = malloc( free_list->element_size ); #endif } return ret; }
/************************************************************************ * Function : SearchByTarget * * Parameters: * IN int Mx:Number of seconds to wait, to collect all the * responses. * char *St: Search target. * void *Cookie: cookie provided by control point application. This * cokie will be returned to application in the * callback. * * Description: * This function creates and send the search request for a specific URL. * * Returns: int * 1 if successful else appropriate error ***************************************************************************/ int SearchByTarget( IN int Mx, IN char *St, IN void *Cookie ) { int socklen = sizeof( struct sockaddr_in ); int *id = NULL; char *ReqBuf; struct sockaddr_in destAddr; fd_set wrSet; SsdpSearchArg *newArg = NULL; int timeTillRead = 0; int handle; struct Handle_Info *ctrlpt_info = NULL; enum SsdpSearchType requestType; unsigned long addr = inet_addr( LOCAL_HOST ); //ThreadData *ThData; ThreadPoolJob job; requestType = ssdp_request_type1( St ); if( requestType == SSDP_SERROR ) { return UPNP_E_INVALID_PARAM; } #ifdef _UPNP_MM_ ReqBuf = ( char * )upnp_malloc( BUFSIZE ); #else ReqBuf = ( char * )malloc( BUFSIZE ); #endif if( ReqBuf == NULL ) return UPNP_E_OUTOF_MEMORY; DBGONLY( UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__, ">>> SSDP SEND >>>\n%s\n", ReqBuf ); )
int iasnprintf( char **ret, int incr, int max, const char *fmt, ... ) { int size = incr; int retc = 0; va_list ap; char *temp = NULL; assert( ret ); assert( fmt ); #ifdef _UPNP_MM_ ( *ret ) = ( char * )upnp_malloc( incr ); #else ( *ret ) = ( char * )malloc( incr ); #endif while( 1 ) { va_start( ap, fmt ); retc = vsnprintf( ( *ret ), size, fmt, ap ); va_end( ap ); if( retc < 0 ) { //size not big enough //and vsnprintf does NOT return the //necessary number of bytes if( ( max != -1 ) && ( size == max ) ) //max reached { break; } incr *= 2; //increase increment //increase size and try again if( ( max != -1 ) && ( ( size + incr ) > max ) ) { incr = ( max - size ); } #ifdef _UPNP_MM_ temp = ( char * )upnp_realloc( ( *ret ), size + incr ); #else temp = ( char * )realloc( ( *ret ), size + incr ); #endif if( temp == NULL ) { break; } size += incr; ( *ret ) = temp; } else { if( ( retc + 1 ) > size ) { //size not big enough //and vsnprintf //returns the necessary //number of bytes if( ( max != -1 ) && ( retc + 1 > max ) ) { retc = -1; break; } #ifdef _UPNP_MM_ temp = ( char * )upnp_realloc( ( *ret ), retc + 1 ); #else temp = ( char * )realloc( ( *ret ), retc + 1 ); #endif if( temp == NULL ) { retc = -1; break; } size = retc + 1; ( *ret ) = temp; //size increased try again } else if( ( retc + 1 ) < size ) { //size is bigger than needed //try and reallocate smaller #ifdef _UPNP_MM_ temp = ( char * )upnp_realloc( ( *ret ), retc + 1 ); #else temp = ( char * )realloc( ( *ret ), retc + 1 ); #endif if( temp != NULL ) { ( *ret ) = temp; } break; } else //size is just right, exit { break; } } } if( retc < 0 ) { #ifdef _UPNP_MM_ upnp_free( ( *ret ) ); #else free( ( *ret ) ); #endif ( *ret ) = NULL; } return retc; }
// strdup static void * sdu() { int size = 0; char *temp = NULL; char *retptr = NULL; while (!size) { size = (random() % MAX_ALLOCATE_SIZE); } TotalAlloc ++; TotalAllocSize += size; temp = (char *)upnp_malloc(size); if (!temp) { if (size) { printf("allocate Warning: out of memory (size : %d)\n", size); upnp_mm_dump(); NullAlloc ++; } return NULL; } bzero(temp, size); memset((void *)temp, 'A', (size - 1)); TotalAlloc ++; retptr = upnp_strdup(temp); upnp_free(temp); /* check phase */ if (retptr) { char *ptr = retptr; int i; int slen = strlen(retptr); TotalAllocSize += size; if (slen != (size - 1)) { printf("strdup error ! duplicated string length : %d [expected: %d]\n", slen, (size - 1)); upnp_mm_dump(); exit(1); } if (slen) { for (i = 0 ; i < slen ; i ++, ptr ++) { if ((*ptr) != 'A') { printf("strdup error ! duplicated character error : %c [expected: %c]\n", *ptr, 'A'); upnp_mm_dump(); exit(1); } } } }else { printf("strdup Warning: out of memory (size : %d)\n", size); upnp_mm_dump(); NullAlloc ++; } return retptr; }
"ssdp_handle_device_request with Cmd %d SEARCH\n", event.Cmd ); UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__, "MAX-AGE = %d\n", maxAge ); UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__, "MX = %d\n", event.Mx ); UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__, "DeviceType = %s\n", event.DeviceType ); UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__, "DeviceUuid = %s\n", event.UDN ); UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__, "ServiceType = %s\n", event.ServiceType ); ) threadArg = #ifdef _UPNP_MM_ ( SsdpSearchReply * ) upnp_malloc( sizeof( SsdpSearchReply ) ); #else ( SsdpSearchReply * ) malloc( sizeof( SsdpSearchReply ) ); #endif if( threadArg == NULL ) { return; } threadArg->handle = handle; threadArg->dest_addr = ( *dest_addr ); threadArg->event = event; threadArg->MaxAge = maxAge; TPJobInit( &job, advertiseAndReplyThread, threadArg ); TPJobSetFreeFunction( &job, ( free_routine ) free );
/************************************************************************ * Function : ssdp_handle_ctrlpt_msg * * Parameters: * IN http_message_t* hmsg: SSDP message from the device * IN struct sockaddr_in* dest_addr: Address of the device * IN xboolean 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 * in the callback * * Description: * This function handles the ssdp messages from the devices. These * messages includes the search replies, advertisement of device coming * alive and bye byes. * * Returns: void * ***************************************************************************/ void ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg, IN struct sockaddr_in *dest_addr, IN xboolean timeout, // only in search reply IN void *cookie ) // only in search reply { int handle; struct Handle_Info *ctrlpt_info = NULL; memptr hdr_value; xboolean is_byebye; // byebye or alive struct Upnp_Discovery param; SsdpEvent event; xboolean nt_found, usn_found, 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; ThreadPoolJob job; // we are assuming that there can be only one client supported at a time HandleLock( ); 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 param.Expires = -1; // assume error if( httpmsg_find_hdr( hmsg, HDR_CACHE_CONTROL, &hdr_value ) != NULL ) { matchstr( hdr_value.buf, hdr_value.length, "%imax-age = %d%0", ¶m.Expires ); } // 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 param.DestAddr = dest_addr; // 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'; param.ServiceVer[0] = '\0'; // not used; version is in ServiceType 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 = #ifdef _UPNP_MM_ ( ResultData * ) upnp_malloc( sizeof( ResultData ) ); #else ( ResultData * ) malloc( sizeof( ResultData ) ); #endif 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 ); } }