Destination Addrress field

Andy Hanton <[email protected]> Sat, 17 Jan 2004 19:47:53 -0500
Newsgroups gmane.linux.upnp-sdk.general
Message-ID <1074386871.7883.1757.camel@andy>
While trying to use libupnp 1.2.1 in a control point, I noticed that the
application was receiving search search result notifications from
non-existent hosts.  The contents of the DestAddr field seemed to be
correct sometimes and random other times.  

It appears that ssdp_event_handler_thread is passing in a pointer to a
member of the data variable to ssdp_handle_ctlpt_msg and then freeing it
at the end of the function.  Unfortunately ssdp_handle_ctlpt_msg passes
the pointer to a new thread and returns.  By the time the thread gets
scheduled the pointer may point to random data.  

I have attached a patch that should correct the problem.  
 
-- 
Andy Hanton <[email protected]>
libupnp_dest_addr.patch (text/x-patch, 2 KB)
--- libupnp-1.2.1/upnp/src/ssdp/ssdp_ctrlpt.c	2003-01-15 16:39:44.000000000 -0500
+++ libupnp-1.2.1.mine/upnp/src/ssdp/ssdp_ctrlpt.c	2004-01-16 14:29:52.000000000 -0500
@@ -69,6 +69,31 @@
 }
 
 /************************************************************************
+* Function : free_send_search_results_data								
+*																	
+* Parameters:														
+*	IN void *the_data: ResultData structure. This structure contains
+*			the destination address of the search.
+*
+* Description:														
+*	This function frees the destination address
+*
+* Returns: VOID
+*	
+***************************************************************************/
+static void
+free_send_search_results_data( void *the_data )
+{
+    ResultData *threadData = ( ResultData * ) the_data;
+
+    if( threadData != NULL ) {
+        // free data
+        free( threadData->param.DestAddr );
+        free( threadData );
+    }
+}
+
+/************************************************************************
 * Function : ssdp_handle_ctrlpt_msg											
 *																	
 * Parameters:														
@@ -149,7 +174,8 @@
     }
 
     // dest addr
-    param.DestAddr = dest_addr;
+    param.DestAddr = malloc(sizeof(struct sockaddr_in));
+    *param.DestAddr = *dest_addr;
 
     // EXT
     param.Ext[0] = '\0';
@@ -241,6 +267,7 @@
 
         // call callback
         ctrlpt_callback( event_type, &param, ctrlpt_cookie );
+        free( param.DestAddr );
 
     } else                      // reply (to a SEARCH)
     {
@@ -327,7 +354,8 @@
                     TPJobInit( &job, ( start_routine ) send_search_result,
                                threadData );
                     TPJobSetPriority( &job, MED_PRIORITY );
-                    TPJobSetFreeFunction( &job, ( free_routine ) free );
+                    TPJobSetFreeFunction( &job, 
+                                          free_send_search_results_data );
                     ThreadPoolAdd( &gRecvThreadPool, &job, NULL );
                 }
             }