Revision: 357
http://pupnp.svn.sourceforge.net/pupnp/?rev=357&view=rev
Author: cnepveu
Date: 2008-04-30 07:17:48 -0700 (Wed, 30 Apr 2008)
Log Message:
-----------
Integrated IPv6 in the UPnP stack.
Modified Paths:
--------------
branches/branch-ipv6/TODO
branches/branch-ipv6/upnp/inc/upnp.h
branches/branch-ipv6/upnp/src/api/upnpapi.c
branches/branch-ipv6/upnp/src/gena/gena_ctrlpt.c
branches/branch-ipv6/upnp/src/gena/gena_device.c
branches/branch-ipv6/upnp/src/genlib/miniserver/miniserver.c
branches/branch-ipv6/upnp/src/genlib/net/http/httpreadwrite.c
branches/branch-ipv6/upnp/src/genlib/net/sock.c
branches/branch-ipv6/upnp/src/genlib/net/uri/uri.c
branches/branch-ipv6/upnp/src/inc/http_client.h
branches/branch-ipv6/upnp/src/inc/miniserver.h
branches/branch-ipv6/upnp/src/inc/sock.h
branches/branch-ipv6/upnp/src/inc/ssdplib.h
branches/branch-ipv6/upnp/src/inc/upnpapi.h
branches/branch-ipv6/upnp/src/inc/uri.h
branches/branch-ipv6/upnp/src/inc/urlconfig.h
branches/branch-ipv6/upnp/src/soap/soap_device.c
branches/branch-ipv6/upnp/src/ssdp/ssdp_ctrlpt.c
branches/branch-ipv6/upnp/src/ssdp/ssdp_device.c
branches/branch-ipv6/upnp/src/ssdp/ssdp_server.c
branches/branch-ipv6/upnp/src/urlconfig/urlconfig.c
Modified: branches/branch-ipv6/TODO
===================================================================
--- branches/branch-ipv6/TODO 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/TODO 2008-04-30 14:17:48 UTC (rev 357)
@@ -18,6 +18,10 @@
- make API clean for large files and 64 bits
+- Why is NUM_HANDLE defined to 200 when we can register only:
+ A) One client(1)
+ B) An IPv4 and IPv6 device (2)
+ NUM_HANDLE should be 3
To Be Decided
=============
Modified: branches/branch-ipv6/upnp/inc/upnp.h
===================================================================
--- branches/branch-ipv6/upnp/inc/upnp.h 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/inc/upnp.h 2008-04-30 14:17:48 UTC (rev 357)
@@ -106,6 +106,7 @@
#endif
#ifndef WIN32
#define SOCKET int
+ #define INVALID_SOCKET (SOCKET)(~0)
#endif
@@ -746,8 +747,8 @@
/** The DOM document describing the result of the action. */
IXML_Document *ActionResult;
- /** IP address of the control point requesting this action. */
- struct in_addr CtrlPtIPAddr;
+ /** Socket address of the control point requesting this action. */
+ struct sockaddr_storage CtrlPtSockaddr;
/** The DOM document containing the information from the
the SOAP header. */
@@ -793,8 +794,8 @@
/** The name of the variable. */
char StateVarName[NAME_SIZE];
- /** IP address of sender requesting the state variable. */
- struct in_addr CtrlPtIPAddr;
+ /** Socket address of sender requesting the state variable. */
+ struct sockaddr_storage CtrlPtSockaddr;
/** The current value of the variable. This needs to be allocated by
* the caller. When finished with it, the SDK frees this {\bf DOMString}. */
@@ -874,7 +875,7 @@
char Ext[LINE_SIZE];
/** The host address of the device responding to the search. */
- struct sockaddr_in DestAddr;
+ struct sockaddr_storage DestAddr;
};
/** Returned along with a {\bf UPNP_EVENT_SUBSCRIBE_COMPLETE} or {\bf
@@ -1189,20 +1190,40 @@
* returned.
*
* @return [unsigned short] The port on which an internal server is
- * listening for UPnP related requests.
+ * listening for IPv4 UPnP related requests.
*/
EXPORT_SPEC unsigned short UpnpGetServerPort(void);
-/** If {\tt NULL} is used as the IP address in {\bf UpnpInit}, then this
+/** If '0' is used as the port number in {\bf UpnpInit}, then this
+ * function can be used to retrieve the actual port allocated to
+ * the SDK. If {\bf UpnpInit} has not succeeded then 0 is
+ * returned.
+ *
+ * @return [unsigned short] The port on which an internal server is
+ * listening for IPv6 UPnP related requests.
+ */
+EXPORT_SPEC unsigned short UpnpGetServerPort6(void);
+
+/** If {\tt NULL} is used as the IPv4 address in {\bf UpnpInit}, then this
* function can be used to retrieve the actual interface address
* on which device is running. If {\bf UpnpInit} has not succeeded
* then {\tt NULL} is returned.
*
- * @return [char*] The IP address on which an internal server is listening
+ * @return [char*] The IPv4 address on which an internal server is listening
* for UPnP related requests.
*/
EXPORT_SPEC char * UpnpGetServerIpAddress(void);
+/** If {\tt NULL} is used as the IPv6 address in {\bf UpnpInit}, then this
+ * function can be used to retrieve the actual interface address
+ * on which device is running. If {\bf UpnpInit} has not succeeded
+ * then {\tt NULL} is returned.
+ *
+ * @return [char*] The IPv6 address on which an internal server is listening
+ * for UPnP related requests.
+ */
+EXPORT_SPEC char * UpnpGetServerIp6Address(void);
+
/** {\bf UpnpRegisterClient} registers a control point application with the
* SDK. A control point application cannot make any other API calls
* until it registers using this function.
@@ -1369,6 +1390,58 @@
the new device handle. */
);
+
+/** {\bf UpnpRegisterRootDevice3} registers a device application for a
+ * specific address family with the SDK. A device application cannot
+ * make any other API calls until it registers using this function.
+ * Device applications can also register as control points (see
+ * {\bf UpnpRegisterClient} to get a control point handle to perform
+ * control point functionality).
+ *
+ * {\bf UpnpRegisterRootDevice} is synchronous and does not generate
+ * any callbacks. Callbacks can occur as soon as this function returns.
+ *
+ * @return [int] An integer representing one of the following:
+ * \begin{itemize}
+ * \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
+ * \item {\tt UPNP_E_FINISH}: The SDK is already terminated or
+ * is not initialized.
+ * \item {\tt UPNP_E_INVALID_DESC}: The description document was not
+ * a valid device description.
+ * \item {\tt UPNP_E_INVALID_URL}: The URL for the description document
+ * is not valid.
+ * \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf Callback} or {\bf Hnd}
+ * is not a valid pointer or {\bf DescURL} is {\tt NULL}.
+ * \item {\tt UPNP_E_NETWORK_ERROR}: A network error occurred.
+ * \item {\tt UPNP_E_SOCKET_WRITE}: An error or timeout occurred writing
+ * to a socket.
+ * \item {\tt UPNP_E_SOCKET_READ}: An error or timeout occurred reading
+ * from a socket.
+ * \item {\tt UPNP_E_SOCKET_BIND}: An error occurred binding a socket.
+ * \item {\tt UPNP_E_SOCKET_CONNECT}: An error occurred connecting the
+ * socket.
+ * \item {\tt UPNP_E_OUTOF_SOCKET}: Too many sockets are currently
+ * allocated.
+ * \item {\tt UPNP_E_OUTOF_MEMORY}: There are insufficient resources to
+ * register this root device.
+ * \end{itemize} */
+
+EXPORT_SPEC int UpnpRegisterRootDevice3(
+ IN const char *DescUrl, /** Pointer to a string containing the
+ description URL for this root device
+ instance. */
+ IN Upnp_FunPtr Callback, /** Pointer to the callback function for
+ receiving asynchronous events. */
+ IN const void *Cookie, /** Pointer to user data returned with the
+ callback function when invoked. */
+ OUT UpnpDevice_Handle *Hnd,/** Pointer to a variable to store the
+ new device handle. */
+ IN const int AddressFamily /** Address family of this device. Can be
+ AF_INET for an IPv4 device, or AF_INET6
+ for an IPv6 device. Defaults to AF_INET. */
+ );
+
+
/** {\bf UpnpUnRegisterClient} unregisters a control point application,
* unsubscribing all active subscriptions. After this call, the
* {\bf UpnpClient_Handle} is no longer valid.
Modified: branches/branch-ipv6/upnp/src/api/upnpapi.c
===================================================================
--- branches/branch-ipv6/upnp/src/api/upnpapi.c 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/src/api/upnpapi.c 2008-04-30 14:17:48 UTC (rev 357)
@@ -66,6 +66,8 @@
#include "soaplib.h"
#include "ThreadPool.h"
#include "membuffer.h"
+#include "sysdep.h"
+#include "uuid.h"
#include "httpreadwrite.h"
@@ -113,8 +115,9 @@
// Contains interface index. (extern'ed in upnp.h)
int gIF_INDEX = -1;
-// local port for the mini-server
- unsigned short LOCAL_PORT;
+// local IPv4 and IPv6 ports for the mini-server
+ unsigned short LOCAL_PORT_V4;
+ unsigned short LOCAL_PORT_V6;
// UPnP device and control point handle table
void *HandleTable[NUM_HANDLE];
@@ -134,15 +137,22 @@
// = 0 if uninitialized, = 1 if initialized.
int UpnpSdkInit = 0;
-// Global variable to denote the state of Upnp SDK device registration.
-// = 0 if unregistered, = 1 if registered.
- int UpnpSdkDeviceRegistered = 0;
-
// Global variable to denote the state of Upnp SDK client registration.
// = 0 if unregistered, = 1 if registered.
int UpnpSdkClientRegistered = 0;
+// Global variable to denote the state of Upnp SDK IPv4 device registration.
+// = 0 if unregistered, = 1 if registered.
+ int UpnpSdkDeviceregisteredV4 = 0;
+// Global variable to denote the state of Upnp SDK IPv6 device registration.
+// = 0 if unregistered, = 1 if registered.
+ int UpnpSdkDeviceregisteredV6 = 0;
+
+// Global variable used in discovery notifications.
+ Upnp_SID gUpnpSdkNLSuuid;
+
+
/****************************************************************************
* Function: UpnpInit2
*
@@ -193,16 +203,17 @@
return retVal;
}
+ // Set the UpnpSdkInit flag to 1 to indicate we're sucessfully initialized.
+ UpnpSdkInit = 1;
+
// Finish initializing the SDK.
retVal = UpnpInitStartServers( DestPort );
if( retVal != UPNP_E_SUCCESS ) {
+ UpnpSdkInit = 0;
ithread_mutex_unlock( &gSDKInitMutex );
return retVal;
}
- // Set the UpnpSdkInit flag to 1 to indicate we're sucessfully initialized.
- UpnpSdkInit = 1;
-
ithread_mutex_unlock( &gSDKInitMutex );
return UPNP_E_SUCCESS;
@@ -260,20 +271,21 @@
}
}
+ // Set the UpnpSdkInit flag to 1 to indicate we're sucessfully initialized.
+ UpnpSdkInit = 1;
+
// Finish initializing the SDK.
retVal = UpnpInitStartServers( DestPort );
if( retVal != UPNP_E_SUCCESS ) {
+ UpnpSdkInit = 0;
ithread_mutex_unlock( &gSDKInitMutex );
return retVal;
}
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
"Host Ip: %s Host Port: %d\n", gIF_IPV4,
- LOCAL_PORT );
+ LOCAL_PORT_V4 );
- // Set the UpnpSdkInit flag to 1 to indicate we're sucessfully initialized.
- UpnpSdkInit = 1;
-
ithread_mutex_unlock( &gSDKInitMutex );
return UPNP_E_SUCCESS;
@@ -387,8 +399,10 @@
PrintThreadPoolStats(&gMiniServerThreadPool, __FILE__, __LINE__, "MiniServer Thread Pool");
#ifdef INCLUDE_DEVICE_APIS
- if( GetDeviceHandleInfo( &device_handle, &temp ) == HND_DEVICE )
+ if( GetDeviceHandleInfo( AF_INET, &device_handle, &temp ) == HND_DEVICE )
UpnpUnRegisterRootDevice( device_handle );
+ if( GetDeviceHandleInfo( AF_INET6, &device_handle, &temp ) == HND_DEVICE )
+ UpnpUnRegisterRootDevice( device_handle );
#endif
#ifdef INCLUDE_CLIENT_APIS
@@ -443,7 +457,7 @@
* Parameters: NONE
*
* Description:
- * Gives back the miniserver port.
+ * Gives back the IPv4 listening miniserver port.
*
* Return Values:
* local port on success, zero on failure.
@@ -455,19 +469,40 @@
if( UpnpSdkInit != 1 )
return 0;
- return LOCAL_PORT;
+ return LOCAL_PORT_V4;
}
+/******************************************************************************
+ * Function: UpnpGetServerPort6
+ *
+ * Parameters: NONE
+ *
+ * Description:
+ * Gives back the IPv6 listening miniserver port.
+ *
+ * Return Values:
+ * local port on success, zero on failure.
+ *****************************************************************************/
+unsigned short
+UpnpGetServerPort6( void )
+{
+
+ if( UpnpSdkInit != 1 )
+ return 0;
+
+ return LOCAL_PORT_V6;
+}
+
/***************************************************************************
* Function: UpnpGetServerIpAddress
*
* Parameters: NONE
*
* Description:
- * Gives back the local ipaddress.
+ * Gives back the local IPv4 ipaddress.
*
* Return Values: char *
- * return the IP address string on success else NULL of failure
+ * return the IPv4 address string on success else NULL of failure
***************************************************************************/
char *
UpnpGetServerIpAddress( void )
@@ -479,6 +514,27 @@
return gIF_IPV4;
}
+/***************************************************************************
+ * Function: UpnpGetServerIp6Address
+ *
+ * Parameters: NONE
+ *
+ * Description:
+ * Gives back the local IPv6 ipaddress.
+ *
+ * Return Values: char *
+ * return the IPv6 address string on success else NULL of failure
+ ***************************************************************************/
+char *
+UpnpGetServerIp6Address( void )
+{
+
+ if( UpnpSdkInit != 1 )
+ return NULL;
+
+ return gIF_IPV6;
+}
+
#ifdef INCLUDE_DEVICE_APIS
#if 0
@@ -581,19 +637,19 @@
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
"Inside UpnpRegisterRootDevice\n" );
-
+
HandleLock();
- if( UpnpSdkDeviceRegistered ) {
- HandleUnlock();
- return UPNP_E_ALREADY_REGISTERED;
- }
-
if( Hnd == NULL || Fun == NULL ||
DescUrl == NULL || strlen( DescUrl ) == 0 ) {
HandleUnlock();
return UPNP_E_INVALID_PARAM;
}
+ if( UpnpSdkDeviceregisteredV4 == 1 ) {
+ HandleUnlock();
+ return UPNP_E_ALREADY_REGISTERED;
+ }
+
if( ( *Hnd = GetFreeHandle() ) == UPNP_E_OUTOF_HANDLE ) {
HandleUnlock();
return UPNP_E_OUTOF_MEMORY;
@@ -622,6 +678,7 @@
CLIENTONLY( HInfo->ClientSubList = NULL; )
HInfo->MaxSubscriptions = UPNP_INFINITE;
HInfo->MaxSubscriptionTimeOut = UPNP_INFINITE;
+ HInfo->DeviceAf = AF_INET;
if( ( retVal =
UpnpDownloadXmlDoc( HInfo->DescURL, &( HInfo->DescDocument ) ) )
@@ -674,7 +731,8 @@
"\nUpnpRegisterRootDevice2: Empty service table\n" );
}
- UpnpSdkDeviceRegistered = 1;
+ UpnpSdkDeviceregisteredV4 = 1;
+
HandleUnlock();
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
"Exiting RegisterRootDevice Successfully\n" );
@@ -682,6 +740,7 @@
return UPNP_E_SUCCESS;
}
+
#endif // INCLUDE_DEVICE_APIS
#ifdef INCLUDE_DEVICE_APIS
@@ -780,13 +839,6 @@
return UPNP_E_FINISH;
}
- HandleLock();
- if( !UpnpSdkDeviceRegistered ) {
- HandleUnlock();
- return UPNP_E_INVALID_HANDLE;
- }
- HandleUnlock();
-
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
"Inside UpnpUnRegisterRootDevice \n" );
#if EXCLUDE_GENA == 0
@@ -802,7 +854,7 @@
HandleUnlock();
#if EXCLUDE_SSDP == 0
- retVal = AdvertiseAndReply( -1, Hnd, 0, ( struct sockaddr_in * )NULL,
+ retVal = AdvertiseAndReply( -1, Hnd, 0, ( struct sockaddr * )NULL,
( char * )NULL, ( char * )NULL,
( char * )NULL, HInfo->MaxAge );
#endif
@@ -825,8 +877,13 @@
}
#endif // INTERNAL_WEB_SERVER
+ if( HInfo->DeviceAf == AF_INET ) {
+ UpnpSdkDeviceregisteredV4 = 0;
+ } else if( HInfo->DeviceAf == AF_INET6 ) {
+ UpnpSdkDeviceregisteredV6 = 0;
+ }
+
FreeHandle( Hnd );
- UpnpSdkDeviceRegistered = 0;
HandleUnlock();
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
@@ -882,27 +939,53 @@
* Function: get_server_addr
*
* Parameters:
- * OUT struct sockaddr_in* serverAddr: pointer to server address
+ * OUT struct sockaddr* serverAddr: pointer to server address
* structure
*
* Description:
- * This function fills the sockadr_in with miniserver information.
+ * This function fills the sockadr with IPv4 miniserver information.
*
* Return Values: VOID
*
***************************************************************************/
static void
-get_server_addr( OUT struct sockaddr_in *serverAddr )
+get_server_addr( OUT struct sockaddr *serverAddr )
{
- memset( serverAddr, 0, sizeof( struct sockaddr_in ) );
+ struct sockaddr_in* sa4 = (struct sockaddr_in*)serverAddr;
- serverAddr->sin_family = AF_INET;
- serverAddr->sin_port = htons( LOCAL_PORT );
- //inet_aton( gIF_IPV4, &serverAddr->sin_addr );
- serverAddr->sin_addr.s_addr = inet_addr( gIF_IPV4 );
+ memset( serverAddr, 0, sizeof(struct sockaddr_storage) );
+
+ sa4->sin_family = AF_INET;
+ inet_pton( AF_INET, gIF_IPV4, &sa4->sin_addr );
+ sa4->sin_port = htons( LOCAL_PORT_V4 );
}
/**************************************************************************
+ * Function: get_server_addr6
+ *
+ * Parameters:
+ * OUT struct sockaddr* serverAddr: pointer to server address
+ * structure
+ *
+ * Description:
+ * This function fills the sockadr with IPv6 miniserver information.
+ *
+ * Return Values: VOID
+ *
+ ***************************************************************************/
+static void
+get_server_addr6( OUT struct sockaddr *serverAddr )
+{
+ struct sockaddr_in6* sa6 = (struct sockaddr_in6*)serverAddr;
+
+ memset( serverAddr, 0, sizeof(struct sockaddr_storage) );
+
+ sa6->sin6_family = AF_INET6;
+ inet_pton(AF_INET6, gIF_IPV6, &sa6->sin6_addr );
+ sa6->sin6_port = htons( LOCAL_PORT_V6 );
+}
+
+/**************************************************************************
* Function: GetDescDocumentAndURL ( In the case of device)
*
* Parameters:
@@ -911,8 +994,9 @@
* IN char* description:
* IN unsigned int bufferLen:
* IN int config_baseURL:
+ * IN int AddressFamily:
* OUT IXML_Document **xmlDoc:
- * OUT char descURL[LINE_SIZE]:
+ * OUT char descURL[LINE_SIZE]:
*
* Description:
* This function fills the sockadr_in with miniserver information.
@@ -925,6 +1009,7 @@
IN char *description,
IN unsigned int bufferLen,
IN int config_baseURL,
+ IN int AddressFamily,
OUT IXML_Document ** xmlDoc,
OUT char descURL[LINE_SIZE] )
{
@@ -937,7 +1022,7 @@
size_t num_read;
time_t last_modified;
struct stat file_info;
- struct sockaddr_in serverAddr;
+ struct sockaddr_storage serverAddr;
int rc = UPNP_E_SUCCESS;
if( description == NULL ) {
@@ -1016,10 +1101,13 @@
strcpy( aliasStr, temp_str );
}
- get_server_addr( &serverAddr );
+ if(AddressFamily == AF_INET)
+ get_server_addr( (struct sockaddr*)&serverAddr );
+ else
+ get_server_addr6( (struct sockaddr*)&serverAddr );
// config
- retVal = configure_urlbase( *xmlDoc, &serverAddr,
+ retVal = configure_urlbase( *xmlDoc, (struct sockaddr*)&serverAddr,
aliasStr, last_modified, descURL );
if( retVal != UPNP_E_SUCCESS ) {
ixmlDocument_free( *xmlDoc );
@@ -1050,6 +1138,7 @@
* IN char* description:
* IN unsigned int bufferLen:
* IN int config_baseURL:
+ * IN int AddressFamily:
* OUT IXML_Document **xmlDoc:
* OUT char *descURL:
*
@@ -1064,6 +1153,7 @@
IN char *description,
IN unsigned int bufferLen,
IN int config_baseURL,
+ IN int AddressFamily,
OUT IXML_Document ** xmlDoc,
OUT char *descURL )
{
@@ -1146,7 +1236,7 @@
}
HandleLock();
- if( UpnpSdkDeviceRegistered ) {
+ if( UpnpSdkDeviceregisteredV4 == 1 ) {
HandleUnlock();
return UPNP_E_ALREADY_REGISTERED;
}
@@ -1168,7 +1258,8 @@
retVal = GetDescDocumentAndURL(
descriptionType, description, bufferLen,
- config_baseURL, &HInfo->DescDocument, HInfo->DescURL );
+ config_baseURL, AF_INET,
+ &HInfo->DescDocument, HInfo->DescURL );
if( retVal != UPNP_E_SUCCESS ) {
FreeHandle( *Hnd );
@@ -1189,6 +1280,7 @@
CLIENTONLY( HInfo->ClientSubList = NULL; )
HInfo->MaxSubscriptions = UPNP_INFINITE;
HInfo->MaxSubscriptionTimeOut = UPNP_INFINITE;
+ HInfo->DeviceAf = AF_INET;
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"UpnpRegisterRootDevice2: Valid Description\n" );
@@ -1233,7 +1325,8 @@
"\nUpnpRegisterRootDevice2: Empty service table\n" );
}
- UpnpSdkDeviceRegistered = 1;
+ UpnpSdkDeviceregisteredV4 = 1;
+
HandleUnlock();
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Exiting RegisterRootDevice2 Successfully\n" );
@@ -1241,6 +1334,155 @@
return UPNP_E_SUCCESS;
}
+
+/****************************************************************************
+ * Function: UpnpRegisterRootDevice3
+ *
+ * Parameters:
+ * IN const char *DescUrl:Pointer to a string containing the
+ * description URL for this root device instance.
+ * IN Upnp_FunPtr Callback: Pointer to the callback function for
+ * receiving asynchronous events.
+ * IN const void *Cookie: Pointer to user data returned with the
+ * callback function when invoked.
+ * OUT UpnpDevice_Handle *Hnd: Pointer to a variable to store the
+ * new device handle.
+ * IN const int AddressFamily: Registration address family. Can be AF_INET
+ * or AF_INET6.
+ *
+ * Description:
+ * This function registers a device application with
+ * the UPnP Library. A device application cannot make any other API
+ * calls until it registers using this function.
+ *
+ * Return Values:
+ * UPNP_E_SUCCESS on success, nonzero on failure.
+ *****************************************************************************/
+int
+UpnpRegisterRootDevice3( IN const char *DescUrl,
+ IN Upnp_FunPtr Fun,
+ IN const void *Cookie,
+ OUT UpnpDevice_Handle * Hnd,
+ IN const int AddressFamily )
+{
+
+ struct Handle_Info *HInfo;
+ int retVal = 0;
+
+ if( UpnpSdkInit != 1 ) {
+ return UPNP_E_FINISH;
+ }
+
+ UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
+ "Inside UpnpRegisterRootDevice\n" );
+
+ HandleLock();
+ if( Hnd == NULL || Fun == NULL ||
+ DescUrl == NULL || strlen( DescUrl ) == 0 ||
+ (AddressFamily != AF_INET && AddressFamily != AF_INET6) ) {
+ HandleUnlock();
+ return UPNP_E_INVALID_PARAM;
+ }
+
+ if( ( AddressFamily == AF_INET && UpnpSdkDeviceregisteredV4 == 1 ) ||
+ ( AddressFamily == AF_INET6 && UpnpSdkDeviceregisteredV6 == 1 ) ) {
+ HandleUnlock();
+ return UPNP_E_ALREADY_REGISTERED;
+ }
+
+ if( ( *Hnd = GetFreeHandle() ) == UPNP_E_OUTOF_HANDLE ) {
+ HandleUnlock();
+ return UPNP_E_OUTOF_MEMORY;
+ }
+
+ HInfo = ( struct Handle_Info * )malloc( sizeof( struct Handle_Info ) );
+ if( HInfo == NULL ) {
+ HandleUnlock();
+ return UPNP_E_OUTOF_MEMORY;
+ }
+ HandleTable[*Hnd] = HInfo;
+
+ UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
+ "Root device URL is %s\n", DescUrl );
+
+ HInfo->aliasInstalled = 0;
+ HInfo->HType = HND_DEVICE;
+ strcpy( HInfo->DescURL, DescUrl );
+ HInfo->Callback = Fun;
+ HInfo->Cookie = ( void * )Cookie;
+ HInfo->MaxAge = DEFAULT_MAXAGE;
+ HInfo->DeviceList = NULL;
+ HInfo->ServiceList = NULL;
+ HInfo->DescDocument = NULL;
+ CLIENTONLY( ListInit( &HInfo->SsdpSearchList, NULL, NULL ); )
+ CLIENTONLY( HInfo->ClientSubList = NULL; )
+ HInfo->MaxSubscriptions = UPNP_INFINITE;
+ HInfo->MaxSubscriptionTimeOut = UPNP_INFINITE;
+ HInfo->DeviceAf = AddressFamily;
+
+ if( ( retVal =
+ UpnpDownloadXmlDoc( HInfo->DescURL, &( HInfo->DescDocument ) ) )
+ != UPNP_E_SUCCESS ) {
+ CLIENTONLY( ListDestroy( &HInfo->SsdpSearchList, 0 ) );
+ FreeHandle( *Hnd );
+ HandleUnlock();
+ return retVal;
+ }
+
+ UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
+ "UpnpRegisterRootDevice: Valid Description\n" );
+ UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
+ "UpnpRegisterRootDevice: DescURL : %s\n",
+ HInfo->DescURL );
+
+ HInfo->DeviceList =
+ ixmlDocument_getElementsByTagName( HInfo->DescDocument, "device" );
+ if( !HInfo->DeviceList ) {
+ CLIENTONLY( ListDestroy( &HInfo->SsdpSearchList, 0 ) );
+ ixmlDocument_free( HInfo->DescDocument );
+ FreeHandle( *Hnd );
+ HandleUnlock();
+ UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
+ "UpnpRegisterRootDevice: No devices found for RootDevice\n" );
+ return UPNP_E_INVALID_DESC;
+ }
+
+ HInfo->ServiceList = ixmlDocument_getElementsByTagName(
+ HInfo->DescDocument, "serviceList" );
+ if( !HInfo->ServiceList ) {
+ UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
+ "UpnpRegisterRootDevice: No services found for RootDevice\n" );
+ }
+
+ UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
+ "UpnpRegisterRootDevice: Gena Check\n" );
+ //*******************************
+ // GENA SET UP
+ //*******************************
+ if( getServiceTable( ( IXML_Node * ) HInfo->DescDocument,
+ &HInfo->ServiceTable, HInfo->DescURL ) ) {
+ UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
+ "UpnpRegisterRootDevice: GENA Service Table \n" );
+ UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
+ "Here are the known services: \n" );
+ printServiceTable( &HInfo->ServiceTable, UPNP_INFO, API );
+ } else {
+ UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
+ "\nUpnpRegisterRootDevice2: Empty service table\n" );
+ }
+
+ if( AddressFamily == AF_INET )
+ UpnpSdkDeviceregisteredV4 = 1;
+ else
+ UpnpSdkDeviceregisteredV6 = 1;
+
+ HandleUnlock();
+ UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
+ "Exiting RegisterRootDevice Successfully\n" );
+
+ return UPNP_E_SUCCESS;
+}
+
#endif // INCLUDE_DEVICE_APIS
#ifdef INCLUDE_CLIENT_APIS
@@ -1438,7 +1680,7 @@
Exp = DEFAULT_MAXAGE;
SInfo->MaxAge = Exp;
HandleUnlock();
- retVal = AdvertiseAndReply( 1, Hnd, 0, ( struct sockaddr_in * )NULL,
+ retVal = AdvertiseAndReply( 1, Hnd, 0, ( struct sockaddr * )NULL,
( char * )NULL, ( char * )NULL,
( char * )NULL, Exp );
@@ -3355,6 +3597,7 @@
*****************************************************************************/
int UpnpInitPreamble( void )
{
+ uuid_upnp nls_uuid;
int retVal = 0;
#ifdef WIN32
@@ -3365,7 +3608,7 @@
/* The WinSock DLL is acceptable. Proceed. */
#endif
- srand( time( NULL ) ); // needed by SSDP or other parts
+ srand( (unsigned int)time( NULL ) ); // needed by SSDP or other parts
// Initialize debug output.
retVal = UpnpInitLog();
@@ -3382,6 +3625,11 @@
return retVal;
}
+ // Create the NLS uuid.
+ uuid_create(&nls_uuid);
+ uuid_unpack(&nls_uuid, gUpnpSdkNLSuuid);
+
+ // Init the handle list.
HandleLock();
InitHandleList();
HandleUnlock();
@@ -3513,17 +3761,16 @@
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "Entering UpnpInitStartServers\n" );
#if EXCLUDE_MINISERVER == 0
- if( ( retVal = StartMiniServer( DestPort ) ) <= 0 ) {
+ LOCAL_PORT_V4 = DestPort;
+ LOCAL_PORT_V6 = DestPort;
+ retVal = StartMiniServer( &LOCAL_PORT_V4, &LOCAL_PORT_V6 );
+ if( retVal != UPNP_E_SUCCESS ) {
UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
"Miniserver failed to start" );
UpnpFinish();
- if( retVal != -1 )
- return retVal;
- else // if miniserver is already running for unknown reasons!
- return UPNP_E_INIT_FAILED;
+ return retVal;
}
#endif
- LOCAL_PORT = retVal;
#if EXCLUDE_WEB_SERVER == 0
membuffer_init( &gDocumentRootDir );
@@ -4068,6 +4315,7 @@
* this function.
*
* Description:
+ * NOTE: The logic around the use of this function should be revised.
* This function is to get client handle info
*
* Return Values: HND_CLIENT
@@ -4092,10 +4340,13 @@
} /****************** End of GetClientHandleInfo *********************/
/**************************************************************************
- * Function: GetDeviceHandleInfo
+ * Function: GetDeviceHandleInfo
+ * Retrieves the device handle and information of the first device of the
+ * address family spcified.
*
- * Parameters:
- * IN UpnpDevice_Handle * device_handle_out: device handle pointer
+ * Parameters:
+ * IN int AddressFamily:
+ * OUT UpnpDevice_Handle * device_handle_out: device handle pointer
* (key for the client handle structure).
* OUT struct Handle_Info **HndInfo: Device handle structure passed by
* this function.
@@ -4103,22 +4354,31 @@
* Description:
* This function is to get device handle info.
*
- * Return Values: HND_DEVICE
+ * Return Values: HND_DEVICE or HND_INVALID
*
***************************************************************************/
Upnp_Handle_Type
-GetDeviceHandleInfo( UpnpDevice_Handle * device_handle_out,
+GetDeviceHandleInfo( const int AddressFamily,
+ UpnpDevice_Handle * device_handle_out,
struct Handle_Info ** HndInfo )
{
- ( *device_handle_out ) = 1;
- if( GetHandleInfo( 1, HndInfo ) == HND_DEVICE )
- return HND_DEVICE;
+ // Check if we've got a registered device of the address family specified.
+ if( (AddressFamily == AF_INET && UpnpSdkDeviceregisteredV4 == 0) ||
+ (AddressFamily == AF_INET6 && UpnpSdkDeviceregisteredV6 == 0) ) {
+ *device_handle_out = -1;
+ return HND_INVALID;
+ }
- ( *device_handle_out ) = 2;
- if( GetHandleInfo( 2, HndInfo ) == HND_DEVICE )
- return HND_DEVICE;
- ( *device_handle_out ) = -1;
+ // Find it.
+ for( *device_handle_out=1; *device_handle_out < NUM_HANDLE; (*device_handle_out)++ ) {
+ if( GetHandleInfo( *device_handle_out, HndInfo ) == HND_DEVICE ) {
+ if( (*HndInfo)->DeviceAf == AddressFamily ) {
+ return HND_DEVICE;
+ }
+ }
+ }
+ *device_handle_out = -1;
return HND_INVALID;
} /****************** End of GetDeviceHandleInfo *********************/
Modified: branches/branch-ipv6/upnp/src/gena/gena_ctrlpt.c
===================================================================
--- branches/branch-ipv6/upnp/src/gena/gena_ctrlpt.c 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/src/gena/gena_ctrlpt.c 2008-04-30 14:17:48 UTC (rev 357)
@@ -314,13 +314,23 @@
"TIMEOUT: Second-", timeout_str );
} else {
// subscribe
- return_code = http_MakeMessage(
- &request, 1, 1,
- "q" "sssdsc" "sc" "sscc",
- HTTPMETHOD_SUBSCRIBE, &dest_url,
- "CALLBACK: <http://", gIF_IPV4, ":", LOCAL_PORT, "/>",
- "NT: upnp:event",
- "TIMEOUT: Second-", timeout_str );
+ if( dest_url.hostport.IPaddress.ss_family == AF_INET6 ) {
+ return_code = http_MakeMessage(
+ &request, 1, 1,
+ "q" "sssdsc" "sc" "sscc",
+ HTTPMETHOD_SUBSCRIBE, &dest_url,
+ "CALLBACK: <http://[", gIF_IPV6, "]:", LOCAL_PORT_V6, "/>",
+ "NT: upnp:event",
+ "TIMEOUT: Second-", timeout_str );
+ } else {
+ return_code = http_MakeMessage(
+ &request, 1, 1,
+ "q" "sssdsc" "sc" "sscc",
+ HTTPMETHOD_SUBSCRIBE, &dest_url,
+ "CALLBACK: <http://", gIF_IPV4, ":", LOCAL_PORT_V4, "/>",
+ "NT: upnp:event",
+ "TIMEOUT: Second-", timeout_str );
+ }
}
if( return_code != 0 ) {
return return_code;
Modified: branches/branch-ipv6/upnp/src/gena/gena_device.c
===================================================================
--- branches/branch-ipv6/upnp/src/gena/gena_device.c 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/src/gena/gena_device.c 2008-04-30 14:17:48 UTC (rev 357)
@@ -1352,7 +1352,8 @@
HandleLock();
// CURRENTLY, ONLY ONE DEVICE
- if( GetDeviceHandleInfo( &device_handle, &handle_info ) != HND_DEVICE ) {
+ if( GetDeviceHandleInfo( info->foreign_sockaddr.ss_family ,
+ &device_handle, &handle_info ) != HND_DEVICE ) {
free( event_url_path );
error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
HandleUnlock();
@@ -1527,7 +1528,8 @@
HandleLock();
// CURRENTLY, ONLY SUPPORT ONE DEVICE
- if( GetDeviceHandleInfo( &device_handle, &handle_info ) != HND_DEVICE ) {
+ if( GetDeviceHandleInfo( info->foreign_sockaddr.ss_family,
+ &device_handle, &handle_info ) != HND_DEVICE ) {
error_respond( info, HTTP_PRECONDITION_FAILED, request );
membuffer_destroy( &event_url_path );
return;
@@ -1650,7 +1652,8 @@
HandleLock();
// CURRENTLY, ONLY SUPPORT ONE DEVICE
- if( GetDeviceHandleInfo( &device_handle, &handle_info ) != HND_DEVICE ) {
+ if( GetDeviceHandleInfo( info->foreign_sockaddr.ss_family,
+ &device_handle, &handle_info ) != HND_DEVICE ) {
error_respond( info, HTTP_PRECONDITION_FAILED, request );
membuffer_destroy( &event_url_path );
HandleUnlock();
Modified: branches/branch-ipv6/upnp/src/genlib/miniserver/miniserver.c
===================================================================
--- branches/branch-ipv6/upnp/src/genlib/miniserver/miniserver.c 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/src/genlib/miniserver/miniserver.c 2008-04-30 14:17:48 UTC (rev 357)
@@ -73,8 +73,7 @@
struct mserv_request_t {
int connfd; // connection handle
- struct in_addr foreign_ip_addr;
- unsigned short foreign_ip_port;
+ struct sockaddr_storage foreign_sockaddr;
};
typedef enum { MSERV_IDLE, MSERV_RUNNING, MSERV_STOPPING } MiniServerState;
@@ -272,8 +271,8 @@
//parser_request_init( &parser ); ////LEAK_FIX_MK
hmsg = &parser.msg;
- if( sock_init_with_ip( &info, connfd, request->foreign_ip_addr,
- request->foreign_ip_port ) != UPNP_E_SUCCESS ) {
+ if( sock_init_with_ip( &info, connfd, (struct sockaddr*)&request->foreign_sockaddr )
+ != UPNP_E_SUCCESS ) {
free( request );
httpmsg_destroy( hmsg );
return;
@@ -317,7 +316,7 @@
*
* Parameters:
* IN int connfd - Socket Descriptor on which connection is accepted
- * IN struct sockaddr_in* clientAddr - Clients Address information
+ * IN struct sockaddr* clientAddr - Clients Address information
*
* Description:
* Initilize the thread pool to handle a request.
@@ -327,7 +326,7 @@
************************************************************************/
static UPNP_INLINE void
schedule_request_job( IN int connfd,
- IN struct sockaddr_in *clientAddr )
+ IN struct sockaddr *clientAddr )
{
struct mserv_request_t *request;
ThreadPoolJob job;
@@ -338,14 +337,13 @@
if( request == NULL ) {
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
"mserv %d: out of memory\n", connfd );
- shutdown( request->connfd, SD_BOTH );
+ shutdown( connfd, SD_BOTH );
UpnpCloseSocket( connfd );
return;
}
request->connfd = connfd;
- request->foreign_ip_addr = clientAddr->sin_addr;
- request->foreign_ip_port = ntohs( clientAddr->sin_port );
+ memcpy( &request->foreign_sockaddr, clientAddr, sizeof(request->foreign_sockaddr) );
TPJobInit( &job, ( start_routine ) handle_request, ( void * )request );
TPJobSetFreeFunction( &job, free_handle_request_arg );
@@ -380,28 +378,41 @@
RunMiniServer( MiniServerSockArray *miniSock )
{
char errorBuffer[ERROR_BUFFER_LEN];
- struct sockaddr_in clientAddr;
+ struct sockaddr_storage clientAddr;
socklen_t clientLen;
SOCKET connectHnd;
- SOCKET miniServSock = miniSock->miniServerSock;
+ SOCKET miniServSock4 = miniSock->miniServerSock4;
+ SOCKET miniServSock6 = miniSock->miniServerSock6;
SOCKET miniServStopSock = miniSock->miniServerStopSock;
- SOCKET ssdpSock = miniSock->ssdpSock;
+ SOCKET ssdpSock4 = miniSock->ssdpSock4;
+ SOCKET ssdpSock6 = miniSock->ssdpSock6;
#ifdef INCLUDE_CLIENT_APIS
- SOCKET ssdpReqSock = miniSock->ssdpReqSock;
+ SOCKET ssdpReqSock4 = miniSock->ssdpReqSock4;
+ SOCKET ssdpReqSock6 = miniSock->ssdpReqSock6;
#endif
-
+ char buf_ntop[64];
fd_set expSet;
fd_set rdSet;
- unsigned int maxMiniSock;
+ unsigned int maxMiniSock = 0;
int byteReceived;
char requestBuf[256];
int ret = 0;
- maxMiniSock = max( miniServSock, miniServStopSock) ;
- maxMiniSock = max( maxMiniSock, (SOCKET)(ssdpSock) );
+ if( miniServSock4 != INVALID_SOCKET )
+ maxMiniSock = max( maxMiniSock, miniServSock4 );
+ if( miniServSock6 != INVALID_SOCKET )
+ maxMiniSock = max( maxMiniSock, miniServSock6 );
+ if( ssdpSock4 != INVALID_SOCKET )
+ maxMiniSock = max( maxMiniSock, ssdpSock4 );
+ if( ssdpSock6 != INVALID_SOCKET )
+ maxMiniSock = max( maxMiniSock, ssdpSock6 );
#ifdef INCLUDE_CLIENT_APIS
- maxMiniSock = max( maxMiniSock, (SOCKET)(ssdpReqSock) );
+ if( ssdpReqSock4 != INVALID_SOCKET )
+ maxMiniSock = max( maxMiniSock, ssdpReqSock4 );
+ if( ssdpReqSock6 != INVALID_SOCKET )
+ maxMiniSock = max( maxMiniSock, ssdpReqSock6 );
#endif
+ maxMiniSock = max( maxMiniSock, miniServStopSock) ;
++maxMiniSock;
gMServState = MSERV_RUNNING;
@@ -410,11 +421,20 @@
FD_ZERO( &expSet );
FD_SET( miniServStopSock, &expSet );
- FD_SET( miniServSock, &rdSet );
FD_SET( miniServStopSock, &rdSet );
- FD_SET( ssdpSock, &rdSet );
+ if( miniServSock4 != INVALID_SOCKET )
+ FD_SET( miniServSock4, &rdSet );
+ if( miniServSock6 != INVALID_SOCKET )
+ FD_SET( miniServSock6, &rdSet );
+ if( ssdpSock4 != INVALID_SOCKET )
+ FD_SET( ssdpSock4, &rdSet );
+ if( ssdpSock6 != INVALID_SOCKET )
+ FD_SET( ssdpSock6, &rdSet );
#ifdef INCLUDE_CLIENT_APIS
- FD_SET( ssdpReqSock, &rdSet );
+ if( ssdpReqSock4 != INVALID_SOCKET )
+ FD_SET( ssdpReqSock4, &rdSet );
+ if( ssdpReqSock6 != INVALID_SOCKET )
+ FD_SET( ssdpReqSock6, &rdSet );
#endif
ret = select( maxMiniSock, &rdSet, NULL, &expSet, NULL );
@@ -422,13 +442,14 @@
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
"Error in select(): %s\n", errorBuffer );
- /* Avoid 100% CPU in case of repeated error in select() */
- isleep( 1 );
+ /* Avoid 100% CPU in case of repeated error in select() */
+ isleep( 1 );
continue;
} else {
- if( FD_ISSET( miniServSock, &rdSet ) ) {
- clientLen = sizeof( struct sockaddr_in );
- connectHnd = accept( miniServSock,
+ if( miniServSock6 != INVALID_SOCKET &&
+ FD_ISSET( miniServSock6, &rdSet ) ) {
+ clientLen = sizeof( clientAddr );
+ connectHnd = accept( miniServSock6,
( struct sockaddr * )&clientAddr, &clientLen );
if( connectHnd == -1 ) {
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
@@ -436,49 +457,81 @@
"miniserver: Error in accept(): %s\n", errorBuffer );
continue;
}
- schedule_request_job( connectHnd, &clientAddr );
+ schedule_request_job( connectHnd, (struct sockaddr*)&clientAddr );
}
+ if( miniServSock4 != INVALID_SOCKET &&
+ FD_ISSET( miniServSock4, &rdSet ) ) {
+ clientLen = sizeof( clientAddr );
+ connectHnd = accept( miniServSock4,
+ ( struct sockaddr * )&clientAddr, &clientLen );
+ if( connectHnd == -1 ) {
+ strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
+ UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
+ "miniserver: Error in accept(): %s\n", errorBuffer );
+ continue;
+ }
+ schedule_request_job( connectHnd, (struct sockaddr*)&clientAddr );
+ }
#ifdef INCLUDE_CLIENT_APIS
// ssdp
- if( FD_ISSET( ssdpReqSock, &rdSet ) ) {
- readFromSSDPSocket( ssdpReqSock );
+ if( ssdpReqSock6 != INVALID_SOCKET &&
+ FD_ISSET( ssdpReqSock6, &rdSet ) ) {
+ readFromSSDPSocket( ssdpReqSock6 );
}
+ if( ssdpReqSock4 != INVALID_SOCKET &&
+ FD_ISSET( ssdpReqSock4, &rdSet ) ) {
+ readFromSSDPSocket( ssdpReqSock4 );
+ }
#endif
- if( FD_ISSET( ssdpSock, &rdSet ) ) {
- readFromSSDPSocket( ssdpSock );
+ if( ssdpSock6 != INVALID_SOCKET &&
+ FD_ISSET( ssdpSock6, &rdSet ) ) {
+ readFromSSDPSocket( ssdpSock6 );
}
+ if( ssdpSock4 != INVALID_SOCKET &&
+ FD_ISSET( ssdpSock4, &rdSet ) ) {
+ readFromSSDPSocket( ssdpSock4 );
+ }
if( FD_ISSET( miniServStopSock, &rdSet ) ) {
- clientLen = sizeof( struct sockaddr_in );
- memset( (char *)&clientAddr, 0, sizeof (struct sockaddr_in) );
+ clientLen = sizeof( clientAddr );
+ memset( (char *)&clientAddr, 0, sizeof(clientAddr) );
byteReceived =
recvfrom( miniServStopSock, requestBuf, 25, 0,
( struct sockaddr * )&clientAddr,
&clientLen );
if( byteReceived > 0 ) {
requestBuf[byteReceived] = '\0';
+ inet_ntop(AF_INET,
+ &((struct sockaddr_in*)&clientAddr)->sin_addr,
+ buf_ntop, sizeof(buf_ntop) );
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
"Received response: %s From host %s \n",
- requestBuf, inet_ntoa( clientAddr.sin_addr ) );
+ requestBuf, buf_ntop );
UpnpPrintf( UPNP_PACKET, MSERV, __FILE__, __LINE__,
"Received multicast packet: \n %s\n",
requestBuf );
if( NULL != strstr( requestBuf, "ShutDown" ) ) {
break;
- }
+ }
}
}
}
}
- shutdown( miniServSock, SD_BOTH );
- UpnpCloseSocket( miniServSock );
+ shutdown( miniServSock4, SD_BOTH );
+ UpnpCloseSocket( miniServSock4 );
+ shutdown( miniServSock6, SD_BOTH );
+ UpnpCloseSocket( miniServSock6 );
shutdown( miniServStopSock, SD_BOTH );
UpnpCloseSocket( miniServStopSock );
- shutdown( ssdpSock, SD_BOTH );
- UpnpCloseSocket( ssdpSock );
+ shutdown( ssdpSock4, SD_BOTH );
+ UpnpCloseSocket( ssdpSock4 );
+ shutdown( ssdpSock6, SD_BOTH );
+ UpnpCloseSocket( ssdpSock6 );
#ifdef INCLUDE_CLIENT_APIS
- shutdown( ssdpReqSock, SD_BOTH );
- UpnpCloseSocket( ssdpReqSock );
+ shutdown( ssdpReqSock4, SD_BOTH );
+ UpnpCloseSocket( ssdpReqSock4 );
+ shutdown( ssdpReqSock6, SD_BOTH );
+ UpnpCloseSocket( ssdpReqSock6 );
#endif
free( miniSock );
@@ -503,18 +556,22 @@
static int
get_port( int sockfd )
{
- struct sockaddr_in sockinfo;
+ struct sockaddr_storage sockinfo;
socklen_t len;
int code;
- int port;
+ int port = 0;
- len = sizeof( struct sockaddr_in );
+ len = sizeof( sockinfo );
code = getsockname( sockfd, ( struct sockaddr * )&sockinfo, &len );
if( code == -1 ) {
return -1;
}
- port = ntohs( sockinfo.sin_port );
+ if( sockinfo.ss_family == AF_INET ) {
+ port = ntohs( ((struct sockaddr_in*)&sockinfo)->sin_port );
+ } else if( sockinfo.ss_family == AF_INET6 ) {
+ port = ntohs( ((struct sockaddr_in6*)&sockinfo)->sin6_port );
+ }
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
"sockfd = %d, .... port = %d\n", sockfd, port );
@@ -526,8 +583,10 @@
*
* Parameters:
* MiniServerSockArray *out - Socket Array
- * unsigned short listen_port - port on which the server is
- * listening for incoming connections
+ * unsigned short listen_port4 - port on which the server is
+ * listening for incoming IPv4 connections
+ * unsigned short listen_port6 - port on which the server is
+ * listening for incoming IPv6 connections
*
* Description:
* Creates a STREAM socket, binds to INADDR_ANY and listens for
@@ -546,32 +605,46 @@
************************************************************************/
int
get_miniserver_sockets( MiniServerSockArray * out,
- unsigned short listen_port )
+ unsigned short listen_port4,
+ unsigned short listen_port6 )
{
char errorBuffer[ERROR_BUFFER_LEN];
- struct sockaddr_in serverAddr;
- int listenfd;
- int success;
- unsigned short actual_port;
+ struct sockaddr_storage __ss_v4;
+ struct sockaddr_storage __ss_v6;
+ struct sockaddr_in* serverAddr4 = (struct sockaddr_in*)&__ss_v4;
+ struct sockaddr_in6* serverAddr6 = (struct sockaddr_in6*)&__ss_v6;
+ SOCKET listenfd4, listenfd6;
+ int ret_code;
+ unsigned short actual_port4, actual_port6;
int reuseaddr_on = 0;
int sockError = UPNP_E_SUCCESS;
int errCode = 0;
int miniServerStopSock;
int ret = 0;
- listenfd = socket( AF_INET, SOCK_STREAM, 0 );
- if ( listenfd == -1 ) {
- return UPNP_E_OUTOF_SOCKET; // error creating socket
+ // Create listen socket for IPv4/IPv6. An error here may indicate
+ // that we don't have an IPv4/IPv6 stack.
+ listenfd4 = socket( AF_INET, SOCK_STREAM, 0 );
+ listenfd6 = socket( AF_INET6, SOCK_STREAM, 0 );
+ if( listenfd4 == listenfd6 == INVALID_SOCKET ) {
+ return UPNP_E_OUTOF_SOCKET;
}
+
// As per the IANA specifications for the use of ports by applications
// override the listen port passed in with the first available
- if( listen_port < APPLICATION_LISTENING_PORT )
- listen_port = APPLICATION_LISTENING_PORT;
+ if( listen_port4 < APPLICATION_LISTENING_PORT )
+ listen_port4 = APPLICATION_LISTENING_PORT;
+ if( listen_port6 < APPLICATION_LISTENING_PORT )
+ listen_port6 = APPLICATION_LISTENING_PORT;
- memset( &serverAddr, 0, sizeof( serverAddr ) );
- serverAddr.sin_family = AF_INET;
- serverAddr.sin_addr.s_addr = htonl( INADDR_ANY );
+ memset( &__ss_v4, 0, sizeof( __ss_v4 ) );
+ serverAddr4->sin_family = AF_INET;
+ serverAddr4->sin_addr.s_addr = htonl( INADDR_ANY );
+ memset( &__ss_v6, 0, sizeof( __ss_v6 ) );
+ serverAddr6->sin6_family = AF_INET6;
+ serverAddr6->sin6_addr = in6addr_any;
+
// Getting away with implementation of re-using address:port and instead
// choosing to increment port numbers.
// Keeping the re-use address code as an optional behaviour that can be
@@ -583,95 +656,211 @@
// THIS MAY CAUSE TCP TO BECOME LESS RELIABLE
// HOWEVER IT HAS BEEN SUGESTED FOR TCP SERVERS
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
- "mserv start: resuseaddr set\n" );
- sockError = setsockopt( listenfd, SOL_SOCKET, SO_REUSEADDR,
- (const char *)&reuseaddr_on, sizeof (int) );
- if ( sockError == -1 ) {
- shutdown( listenfd, SD_BOTH );
- UpnpCloseSocket( listenfd );
+ "get_miniserver_sockets: resuseaddr set\n" );
- return UPNP_E_SOCKET_BIND;
+ if( listenfd4 != INVALID_SOCKET ) {
+ sockError = setsockopt( listenfd4, SOL_SOCKET, SO_REUSEADDR,
+ (const char *)&reuseaddr_on, sizeof (int) );
+ if ( sockError == -1 ) {
+ shutdown( listenfd4, SD_BOTH );
+ UpnpCloseSocket( listenfd4 );
+ shutdown( listenfd6, SD_BOTH );
+ UpnpCloseSocket( listenfd6 );
+
+ return UPNP_E_SOCKET_BIND;
+ }
+
+ sockError = bind( listenfd4, (struct sockaddr *)&__ss_v4,
+ sizeof(__ss_v4) );
+ if ( sockError == -1 ) {
+ strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
+ UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
+ "get_miniserver_sockets: Error in IPv4 bind(): %s\n",
+ errorBuffer );
+ shutdown( listenfd4, SD_BOTH );
+ UpnpCloseSocket( listenfd4 );
+ shutdown( listenfd6, SD_BOTH );
+ UpnpCloseSocket( listenfd6 );
+
+ return UPNP_E_SOCKET_BIND; // bind failed
+ }
}
- sockError = bind( listenfd, (struct sockaddr *)&serverAddr,
- sizeof (struct sockaddr_in) );
+ if( listenfd6 != INVALID_SOCKET ) {
+ sockError = setsockopt( listenfd6, SOL_SOCKET, SO_REUSEADDR,
+ (const char *)&reuseaddr_on, sizeof (int) );
+ if ( sockError == -1 ) {
+ shutdown( listenfd4, SD_BOTH );
+ UpnpCloseSocket( listenfd4 );
+ shutdown( listenfd6, SD_BOTH );
+ UpnpCloseSocket( listenfd6 );
+
+ return UPNP_E_SOCKET_BIND;
+ }
+
+ sockError = bind( listenfd6, (struct sockaddr *)&__ss_v6,
+ sizeof(__ss_v6) );
+ if ( sockError == -1 ) {
+ strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
+ UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
+ "get_miniserver_sockets: Error in IPv6 bind(): %s\n",
+ errorBuffer );
+ shutdown( listenfd4, SD_BOTH );
+ UpnpCloseSocket( listenfd4 );
+ shutdown( listenfd6, SD_BOTH );
+ UpnpCloseSocket( listenfd6 );
+
+ return UPNP_E_SOCKET_BIND; // bind failed
+ }
+ }
} else {
- do {
- serverAddr.sin_port = htons( listen_port++ );
- sockError = bind( listenfd, (struct sockaddr *)&serverAddr,
- sizeof (struct sockaddr_in) );
- if ( sockError == -1 ) {
+ if( listenfd4 != INVALID_SOCKET ) {
+ do {
+ serverAddr4->sin_port = htons( listen_port4++ );
+ sockError = bind( listenfd4, (struct sockaddr *)&__ss_v4,
+ sizeof(__ss_v4) );
+ if ( sockError == -1 ) {
#ifdef WIN32
- errCode = WSAGetLastError();
+ errCode = WSAGetLastError();
#else
- errCode = errno;
+ errCode = errno;
#endif
- if( errno == EADDRINUSE ) {
- errCode = 1;
- }
- } else
- errCode = 0;
+ if( errno == EADDRINUSE ) {
+ errCode = 1;
+ }
+ } else
+ errCode = 0;
+ } while ( errCode != 0 );
+ if ( sockError == -1 ) {
+ strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
+ UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
+ "get_miniserver_sockets: Error in IPv4 bind(): %s\n",
+ errorBuffer );
+ shutdown( listenfd4, SD_BOTH );
+ UpnpCloseSocket( listenfd4 );
+ shutdown( listenfd6, SD_BOTH );
+ UpnpCloseSocket( listenfd6 );
- } while ( errCode != 0 );
- }
+ return UPNP_E_SOCKET_BIND; // bind failed
+ }
+ }
- if ( sockError == -1 ) {
- strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
- UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
- "mserv start: Error in bind(): %s\n", errorBuffer );
- shutdown( listenfd, SD_BOTH );
- UpnpCloseSocket( listenfd );
+ if( listenfd6 != INVALID_SOCKET ) {
+ do {
+ serverAddr4->sin_port = htons( listen_port6++ );
+ sockError = bind( listenfd6, (struct sockaddr *)&__ss_v4,
+ sizeof(__ss_v4) );
+ if ( sockError == -1 ) {
+#ifdef WIN32
+ errCode = WSAGetLastError();
+#else
+ errCode = errno;
+#endif
+ if( errno == EADDRINUSE ) {
+ errCode = 1;
+ }
+ } else
+ errCode = 0;
+ } while ( errCode != 0 );
+ if ( sockError == -1 ) {
+ strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
+ UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
+ "get_miniserver_sockets: Error in IPv6 bind(): %s\n",
+ errorBuffer );
+ shutdown( listenfd4, SD_BOTH );
+ UpnpCloseSocket( listenfd4 );
+ shutdown( listenfd6, SD_BOTH );
+ UpnpCloseSocket( listenfd6 );
- return UPNP_E_SOCKET_BIND; // bind failed
+ return UPNP_E_SOCKET_BIND; // bind failed
+ }
+ }
}
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
- "mserv start: bind success\n" );
+ "get_miniserver_sockets: bind successful\n" );
- success = listen( listenfd, SOMAXCONN );
- if ( success == -1 ) {
- strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
- UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
- "mserv start: Error in listen(): %s\n", errorBuffer );
- shutdown( listenfd, SD_BOTH );
- UpnpCloseSocket( listenfd );
+ if( listenfd4 != INVALID_SOCKET ) {
+ ret_code = listen( listenfd4, SOMAXCONN );
+ if ( ret_code == -1 ) {
+ strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
+ UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
+ "mserv start: Error in IPv4 listen(): %s\n", errorBuffer );
+ shutdown( listenfd4, SD_BOTH );
+ UpnpCloseSocket( listenfd4 );
+ shutdown( listenfd6, SD_BOTH );
+ UpnpCloseSocket( listenfd6 );
- return UPNP_E_LISTEN;
+ return UPNP_E_LISTEN;
+ }
+
+ actual_port4 = get_port( listenfd4 );
+ if( actual_port4 <= 0 ) {
+ shutdown( listenfd4, SD_BOTH );
+ UpnpCloseSocket( listenfd4 );
+ shutdown( listenfd6, SD_BOTH );
+ UpnpCloseSocket( listenfd6 );
+
+ return UPNP_E_INTERNAL_ERROR;
+ }
+
+ out->miniServerPort4 = actual_port4;
}
- actual_port = get_port( listenfd );
- if( actual_port <= 0 ) {
- shutdown( listenfd, SD_BOTH );
- UpnpCloseSocket( listenfd );
+ if( listenfd6 != INVALID_SOCKET ) {
+ ret_code = listen( listenfd6, SOMAXCONN );
+ if ( ret_code == -1 ) {
+ strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
+ UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
+ "mserv start: Error in IPv6 listen(): %s\n", errorBuffer );
+ shutdown( listenfd4, SD_BOTH );
+ UpnpCloseSocket( listenfd4 );
+ shutdown( listenfd6, SD_BOTH );
+ UpnpCloseSocket( listenfd6 );
- return UPNP_E_INTERNAL_ERROR;
+ return UPNP_E_LISTEN;
+ }
+
+ actual_port6 = get_port( listenfd6 );
+ if( actual_port6 <= 0 ) {
+ shutdown( listenfd4, SD_BOTH );
+ UpnpCloseSocket( listenfd4 );
+ shutdown( listenfd6, SD_BOTH );
+ UpnpCloseSocket( listenfd6 );
+
+ return UPNP_E_INTERNAL_ERROR;
+ }
+
+ out->miniServerPort6 = actual_port6;
}
- out->miniServerPort = actual_port;
-
miniServerStopSock = socket( AF_INET, SOCK_DGRAM, 0 );
if ( miniServerStopSock == -1 ) {
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
UpnpPrintf( UPNP_CRITICAL, MSERV, __FILE__, __LINE__,
"Error in socket(): %s\n", errorBuffer );
- shutdown( listenfd, SD_BOTH );
- UpnpCloseSocket( listenfd );
+ shutdown( listenfd4, SD_BOTH );
+ UpnpCloseSocket( listenfd4 );
+ shutdown( listenfd6, SD_BOTH );
+ UpnpCloseSocket( listenfd6 );
return UPNP_E_OUTOF_SOCKET;
}
// bind to local socket
- memset( ( char * )&serverAddr, 0, sizeof( struct sockaddr_in ) );
- serverAddr.sin_family = AF_INET;
- serverAddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );
- ret = bind( miniServerStopSock, (struct sockaddr *)&serverAddr,
- sizeof (serverAddr) );
+ memset( &__ss_v4, 0, sizeof( __ss_v4 ) );
+ serverAddr4->sin_family = AF_INET;
+ serverAddr4->sin_addr.s_addr = inet_addr( "127.0.0.1" );
+ ret = bind( miniServerStopSock, (struct sockaddr *)&__ss_v4,
+ sizeof(__ss_v4) );
if ( ret == -1 ) {
UpnpPrintf( UPNP_CRITICAL,
MSERV, __FILE__, __LINE__,
"Error in binding localhost!!!\n" );
- shutdown( listenfd, SD_BOTH );
- UpnpCloseSocket( listenfd );
+ shutdown( listenfd4, SD_BOTH );
+ UpnpCloseSocket( listenfd4 );
+ shutdown( listenfd6, SD_BOTH );
+ UpnpCloseSocket( listenfd6 );
shutdown( miniServerStopSock, SD_BOTH );
UpnpCloseSocket( miniServerStopSock );
@@ -682,14 +871,17 @@
if ( miniStopSockPort <= 0 ) {
shutdown( miniServerStopSock, SD_BOTH );
UpnpCloseSocket( miniServerStopSock );
- shutdown( listenfd, SD_BOTH );
- UpnpCloseSocket( listenfd );
+ shutdown( listenfd4, SD_BOTH );
+ UpnpCloseSocket( listenfd4 );
+ shutdown( listenfd6, SD_BOTH );
+ UpnpCloseSocket( listenfd6 );
return UPNP_E_INTERNAL_ERROR;
}
out->stopPort = miniStopSockPort;
- out->miniServerSock = listenfd;
+ out->miniServerSock4 = listenfd4;
+ out->miniServerSock6 = listenfd6;
out->miniServerStopSock = miniServerStopSock;
return UPNP_E_SUCCESS;
@@ -698,27 +890,29 @@
/************************************************************************
* Function: StartMiniServer
*
- * Parameters :
- * unsigned short listen_port - Port on which the server listens for
- * incoming connections
+ * Parameters:
+ * IN OUT unsigned short *listen_port4 ; Port on which the server
+ * listens for incoming IPv4 connections.
+ * IN OUT unsigned short *listen_port6 ; Port on which the server
+ * listens for incoming IPv6 connections.
*
- * Description:
- * Initialize the sockets functionality for the
+ * Description: Initialize the sockets functionality for the
* Miniserver. Initialize a thread pool job to run the MiniServer
* and the job to the thread pool. If listen port is 0, port is
* dynamically picked
*
- * Use timer mechanism to start the MiniServer, failure to meet the
+ * Use timer mechanism to start the MiniServer, failure to meet the
* allowed delay aborts the attempt to launch the MiniServer.
*
- * Return: int
- * Actual port socket is bound to - On Success
- * A negative number UPNP_E_XXX - On Error
+ * Return: int;
+ * On success: UPNP_E_SUCCESS
+ * On error: PNP_E_XXX
************************************************************************/
int
-StartMiniServer( unsigned short listen_port )
+StartMiniServer( unsigned short* listen_port4,
+ unsigned short* listen_port6 )
{
- int success;
+ int ret_code;
int count;
int max_count = 10000;
@@ -733,39 +927,48 @@
if( miniSocket == NULL ) {
return UPNP_E_OUTOF_MEMORY;
}
+ memset( miniSocket, 0, sizeof(*miniSocket) );
- success = get_miniserver_sockets( miniSocket, listen_port );
- if( success != UPNP_E_SUCCESS ) {
+ ret_code = get_miniserver_sockets( miniSocket, *listen_port4, *listen_port6 );
+ if( ret_code != UPNP_E_SUCCESS ) {
free( miniSocket );
- return success;
+ return ret_code;
}
- success = get_ssdp_sockets( miniSocket );
- if( success != UPNP_E_SUCCESS ) {
- shutdown( miniSocket->miniServerSock, SD_BOTH );
- UpnpCloseSocket( miniSocket->miniServerSock );
+ ret_code = get_ssdp_sockets( miniSocket );
+ if( ret_code != UPNP_E_SUCCESS ) {
+ shutdown( miniSocket->miniServerSock4, SD_BOTH );
+ UpnpCloseSocket( miniSocket->miniServerSock4 );
+ shutdown( miniSocket->miniServerSock6, SD_BOTH );
+ UpnpCloseSocket( miniSocket->miniServerSock6 );
shutdown( miniSocket->miniServerStopSock, SD_BOTH );
UpnpCloseSocket( miniSocket->miniServerStopSock );
free( miniSocket );
- return success;
+ return ret_code;
}
TPJobInit( &job, (start_routine)RunMiniServer, (void *)miniSocket );
TPJobSetPriority( &job, MED_PRIORITY );
TPJobSetFreeFunction( &job, ( free_routine ) free );
- success = ThreadPoolAddPersistent( &gMiniServerThreadPool, &job, NULL );
- if ( success < 0 ) {
- shutdown( miniSocket->miniServerSock, SD_BOTH );
- UpnpCloseSocket( miniSocket->miniServerSock );
+ ret_code = ThreadPoolAddPersistent( &gMiniServerThreadPool, &job, NULL );
+ if ( ret_code < 0 ) {
+ shutdown( miniSocket->miniServerSock4, SD_BOTH );
+ UpnpCloseSocket( miniSocket->miniServerSock4 );
+ shutdown( miniSocket->miniServerSock6, SD_BOTH );
+ UpnpCloseSocket( miniSocket->miniServerSock6 );
shutdown( miniSocket->miniServerStopSock, SD_BOTH );
UpnpCloseSocket( miniSocket->miniServerStopSock );
- shutdown( miniSocket->ssdpSock, SD_BOTH );
- UpnpCloseSocket( miniSocket->ssdpSock );
+ shutdown( miniSocket->ssdpSock4, SD_BOTH );
+ UpnpCloseSocket( miniSocket->ssdpSock4 );
+ shutdown( miniSocket->ssdpSock6, SD_BOTH );
+ UpnpCloseSocket( miniSocket->ssdpSock6 );
#ifdef INCLUDE_CLIENT_APIS
- shutdown( miniSocket->ssdpReqSock, SD_BOTH );
- UpnpCloseSocket( miniSocket->ssdpReqSock );
+ shutdown( miniSocket->ssdpReqSock4, SD_BOTH );
+ UpnpCloseSocket( miniSocket->ssdpReqSock4 );
+ shutdown( miniSocket->ssdpReqSock6, SD_BOTH );
+ UpnpCloseSocket( miniSocket->ssdpReqSock6 );
#endif
return UPNP_E_OUTOF_MEMORY;
@@ -779,21 +982,29 @@
// taking too long to start that thread
if ( count >= max_count ) {
- shutdown( miniSocket->miniServerSock, SD_BOTH );
- UpnpCloseSocket( miniSocket->miniServerSock );
+ shutdown( miniSocket->miniServerSock4, SD_BOTH );
+ UpnpCloseSocket( miniSocket->miniServerSock4 );
+ shutdown( miniSocket->miniServerSock6, SD_BOTH );
+ UpnpCloseSocket( miniSocket->miniServerSock6 );
shutdown( miniSocket->miniServerStopSock, SD_BOTH );
UpnpCloseSocket( miniSocket->miniServerStopSock );
- shutdown( miniSocket->ssdpSock, SD_BOTH );
- UpnpCloseSocket( miniSocket->ssdpSock );
+ shutdown( miniSocket->ssdpSock4, SD_BOTH );
+ UpnpCloseSocket( miniSocket->ssdpSock4 );
+ shutdown( miniSocket->ssdpSock6, SD_BOTH );
+ UpnpCloseSocket( miniSocket->ssdpSock6 );
#ifdef INCLUDE_CLIENT_APIS
- shutdown( miniSocket->ssdpReqSock, SD_BOTH );
- UpnpCloseSocket( miniSocket->ssdpReqSock );
+ shutdown( miniSocket->ssdpReqSock4, SD_BOTH );
+ UpnpCloseSocket( miniSocket->ssdpReqSock4 );
+ shutdown( miniSocket->ssdpReqSock6, SD_BOTH );
+ UpnpCloseSocket( miniSocket->ssdpReqSock6 );
#endif
return UPNP_E_INTERNAL_ERROR;
}
+ *listen_port4 = miniSocket->miniServerPort4;
+ *listen_port6 = miniSocket->miniServerPort6;
- return miniSocket->miniServerPort;
+ return UPNP_E_SUCCESS;
}
/************************************************************************
@@ -814,7 +1025,7 @@
{
char errorBuffer[ERROR_BUFFER_LEN];
int socklen = sizeof( struct sockaddr_in );
- int sock;
+ SOCKET sock;
struct sockaddr_in ssdpAddr;
char buf[256] = "ShutDown";
int bufLen = strlen( buf );
Modified: branches/branch-ipv6/upnp/src/genlib/net/http/httpreadwrite.c
===================================================================
--- branches/branch-ipv6/upnp/src/genlib/net/http/httpreadwrite.c 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/src/genlib/net/http/httpreadwrite.c 2008-04-30 14:17:48 UTC (rev 357)
@@ -175,13 +175,13 @@
http_FixUrl( destination_url, url );
- connfd = socket( AF_INET, SOCK_STREAM, 0 );
+ connfd = socket( url->hostport.IPaddress.ss_family, SOCK_STREAM, 0 );
if( connfd == -1 ) {
return UPNP_E_OUTOF_SOCKET;
}
- if( connect( connfd, ( struct sockaddr * )&url->hostport.IPv4address,
- sizeof( struct sockaddr_in ) ) == -1 ) {
+ if( connect( connfd, ( struct sockaddr * )&url->hostport.IPaddress,
+ sizeof( url->hostport.IPaddress ) ) == -1 ) {
#ifdef WIN32
UpnpPrintf(UPNP_CRITICAL, HTTP, __FILE__, __LINE__,
"connect error: %d\n", WSAGetLastError());
@@ -521,7 +521,7 @@
int http_error_code;
SOCKINFO info;
- tcp_connection = socket( AF_INET, SOCK_STREAM, 0 );
+ tcp_connection = socket( destination->hostport.IPaddress.ss_family, SOCK_STREAM, 0 );
if( tcp_connection == -1 ) {
parser_response_init( response, req_method );
return UPNP_E_SOCKET_ERROR;
@@ -535,7 +535,7 @@
// connect
ret_code = connect( info.socket,
( struct sockaddr * )&destination->hostport.
- IPv4address, sizeof( struct sockaddr_in ) );
+ IPaddress, sizeof( struct sockaddr_storage ) );
if( ret_code == -1 ) {
sock_destroy( &info, SD_BOTH );
@@ -1005,7 +1005,7 @@
handle->contentLength = contentLength;
- tcp_connection = socket( AF_INET, SOCK_STREAM, 0 );
+ tcp_connection = socket( url.hostport.IPaddress.ss_family, SOCK_STREAM, 0 );
if( tcp_connection == -1 ) {
ret_code = UPNP_E_SOCKET_ERROR;
goto errorHandler;
@@ -1019,8 +1019,8 @@
}
ret_code = connect( handle->sock_info.socket,
- ( struct sockaddr * )&url.hostport.IPv4address,
- sizeof( struct sockaddr_in ) );
+ ( struct sockaddr * )&url.hostport.IPaddress,
+ sizeof( struct sockaddr_storage ) );
if( ret_code == -1 ) {
sock_destroy( &handle->sock_info, SD_BOTH );
@@ -1587,7 +1587,7 @@
handle->cancel = 0;
parser_response_init( &handle->response, HTTPMETHOD_GET );
- tcp_connection = socket( AF_INET, SOCK_STREAM, 0 );
+ tcp_connection = socket( peer->hostport.IPaddress.ss_family, SOCK_STREAM, 0 );
if( tcp_connection == -1 ) {
ret_code = UPNP_E_SOCKET_ERROR;
goto errorHandler;
@@ -1601,8 +1601,8 @@
}
ret_code = connect( handle->sock_info.socket,
- ( struct sockaddr * )&peer->hostport.IPv4address,
- sizeof( struct sockaddr_in ) );
+ ( struct sockaddr * )&peer->hostport.IPaddress,
+ sizeof( struct sockaddr_storage ) );
if( ret_code == -1 ) {
sock_destroy( &handle->sock_info, SD_BOTH );
@@ -2236,7 +2236,7 @@
handle->entity_offset = 0;
parser_response_init( &handle->response, HTTPMETHOD_GET );
- tcp_connection = socket( AF_INET, SOCK_STREAM, 0 );
+ tcp_connection = socket( url.hostport.IPaddress.ss_family, SOCK_STREAM, 0 );
if( tcp_connection == -1 ) {
errCode = UPNP_E_SOCKET_ERROR;
free( handle );
@@ -2252,8 +2252,8 @@
}
errCode = connect( handle->sock_info.socket,
- ( struct sockaddr * )&url.hostport.IPv4address,
- sizeof( struct sockaddr_in ) );
+ ( struct sockaddr * )&url.hostport.IPaddress,
+ sizeof( struct sockaddr_storage ) );
if( errCode == -1 ) {
sock_destroy( &handle->sock_info, SD_BOTH );
errCode = UPNP_E_SOCKET_CONNECT;
Modified: branches/branch-ipv6/upnp/src/genlib/net/sock.c
===================================================================
--- branches/branch-ipv6/upnp/src/genlib/net/sock.c 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/src/genlib/net/sock.c 2008-04-30 14:17:48 UTC (rev 357)
@@ -62,7 +62,7 @@
*
* Parameters :
* OUT SOCKINFO* info ; Socket Information Object
-* IN int sockfd ; Socket Descriptor
+* IN SOCKET sockfd ; Socket Descriptor
*
* Description : Assign the passed in socket descriptor to socket
* descriptor in the SOCKINFO structure.
@@ -76,7 +76,7 @@
************************************************************************/
int
sock_init( OUT SOCKINFO * info,
- IN int sockfd )
+ IN SOCKET sockfd )
{
assert( info );
@@ -92,9 +92,8 @@
*
* Parameters :
* OUT SOCKINFO* info ; Socket Information Object
-* IN int sockfd ; Socket Descriptor
-* IN struct in_addr foreign_ip_addr ; Remote IP Address
-* IN unsigned short foreign_ip_port ; Remote Port number
+* IN SOCKET sockfd ; Socket Descriptor
+* IN struct sockaddr* foreign_sockaddr; remote socket address.
*
* Description : Calls the sock_init function and assigns the passed in
* IP address and port to the IP address and port in the SOCKINFO
@@ -109,9 +108,8 @@
************************************************************************/
int
sock_init_with_ip( OUT SOCKINFO * info,
- IN int sockfd,
- IN struct in_addr foreign_ip_addr,
- IN unsigned short foreign_ip_port )
+ IN SOCKET sockfd,
+ IN struct sockaddr* foreign_sockaddr )
{
int ret;
@@ -120,8 +118,8 @@
return ret;
}
- info->foreign_ip_addr = foreign_ip_addr;
- info->foreign_ip_port = foreign_ip_port;
+ memcpy( &info->foreign_sockaddr, foreign_sockaddr,
+ sizeof( info->foreign_sockaddr) );
return UPNP_E_SUCCESS;
}
@@ -149,9 +147,11 @@
sock_destroy( INOUT SOCKINFO * info,
int ShutdownMethod )
{
- shutdown( info->socket, ShutdownMethod );
- if( UpnpCloseSocket( info->socket ) == -1 ) {
- return UPNP_E_SOCKET_ERROR;
+ if( info->socket != INVALID_SOCKET ) {
+ shutdown( info->socket, ShutdownMethod );
+ if( UpnpCloseSocket( info->socket ) == -1 ) {
+ return UPNP_E_SOCKET_ERROR;
+ }
}
return UPNP_E_SUCCESS;
@@ -190,7 +190,7 @@
struct timeval timeout;
int numBytes;
time_t start_time = time( NULL );
- int sockfd = info->socket;
+ SOCKET sockfd = info->socket;
long bytes_sent = 0,
byte_left = 0,
num_written;
@@ -202,9 +202,9 @@
FD_ZERO( &readSet );
FD_ZERO( &writeSet );
if( bRead ) {
- FD_SET( ( unsigned )sockfd, &readSet );
+ FD_SET( sockfd, &readSet );
} else {
- FD_SET( ( unsigned )sockfd, &writeSet );
+ FD_SET( sockfd, &writeSet );
}
timeout.tv_sec = *timeoutSecs;
Modified: branches/branch-ipv6/upnp/src/genlib/net/uri/uri.c
===================================================================
--- branches/branch-ipv6/upnp/src/genlib/net/uri/uri.c 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/src/genlib/net/uri/uri.c 2008-04-30 14:17:48 UTC (rev 357)
@@ -41,6 +41,7 @@
#endif
#include "config.h"
#include "uri.h"
+#include "upnpapi.h"
/************************************************************************
@@ -220,28 +221,6 @@
return i;
}
-/************************************************************************
-* Function : copy_sockaddr_in
-*
-* Parameters :
-* const struct sockaddr_in *in ; Source socket address object
-* struct sockaddr_in *out ; Destination socket address object
-*
-* Description : Copies one socket address into another
-*
-* Return : void ;
-*
-* Note :
-************************************************************************/
-void
-copy_sockaddr_in( const struct sockaddr_in *in,
- struct sockaddr_in *out )
-{
- memset( out->sin_zero, 0, 8 );
- out->sin_family = in->sin_family;
- out->sin_port = in->sin_port;
- out->sin_addr.s_addr = in->sin_addr.s_addr;
-}
/************************************************************************
* Function : copy_token
@@ -324,8 +303,9 @@
in->URLs, &out->parsedURLs[i].hostport.text,
out->URLs );
- copy_sockaddr_in( &in->parsedURLs[i].hostport.IPv4address,
- &out->parsedURLs[i].hostport.IPv4address );
+ memcpy( &out->parsedURLs[i].hostport.IPaddress,
+ &in->parsedURLs[i].hostport.IPaddress,
+ sizeof(struct sockaddr_storage) );
}
out->size = in->size;
return HTTP_SUCCESS;
@@ -486,6 +466,8 @@
return memcmp( in1->buff, in2->buff, in1->size );
}
+// DEAD CODE.
+#if 0
/************************************************************************
* Function : parse_port
*
@@ -521,13 +503,14 @@
*out = htons( temp );
return finger - port;
}
+#endif
/************************************************************************
* Function : parse_hostport
*
* Parameters :
* char *in ; string of characters representing host and port
-* int max ; sets a maximum limit
+* int max ; sets a maximum limit (not used).
* hostport_type *out ; out parameter where the host and port
* are represented as an internet address
*
@@ -536,7 +519,8 @@
* hostport_type struct with internet address and a token
* representing the full host and port. uses gethostbyname.
*
-* Return : int ;
+* Returns: The number of characters that form up the host and port.
+* UPNP_E_INVALID_URL on error.
*
* Note :
************************************************************************/
@@ -545,165 +529,145 @@
int max,
hostport_type * out )
{
-#define BUFFER_SIZE 8192
+ char workbuf[256];
+ char* c;
+ struct sockaddr_in* sai4 = (struct sockaddr_in*)&out->IPaddress;
+ struct sockaddr_in6* sai6 = (struct sockaddr_in6*)&out->IPaddress;
+ char *srvname = NULL;
+ char *srvport = NULL;
+ char *last_dot = NULL;
+ unsigned short int port;
+ int af = AF_UNSPEC;
+ int hostport_size;
+ int has_port = 0;
+ int ret;
- int i = 0;
- int begin_port;
- int hostport_size = 0;
- int host_size = 0;
-#if !defined(WIN32) && !(defined(__OSX__) || defined(__APPLE__))
- char temp_hostbyname_buff[BUFFER_SIZE];
- struct hostent h_buf;
-#endif
- struct hostent *h = NULL;
- int errcode = 0;
- char *temp_host_name = NULL;
- int last_dot = -1;
+ memset( out, 0, sizeof(hostport_type) );
- out->text.size = 0;
- out->text.buff = NULL;
+ // Work on a copy of the input string.
+ strncpy( workbuf, in, sizeof(workbuf) );
- out->IPv4address.sin_port = htons( 80 ); //default port is 80
- memset( &out->IPv4address.sin_zero, 0, 8 );
-
- while( ( i < max ) && ( in[i] != ':' ) && ( in[i] != '/' )
- && ( ( isalnum( in[i] ) ) || ( in[i] == '.' )
- || ( in[i] == '-' ) ) ) {
- i++;
- if( in[i] == '.' ) {
- last_dot = i;
+ c = workbuf;
+ if( *c == '[' ) {
+ // IPv6 addresses are enclosed in square brackets.
+ srvname = ++c;
+ while( *c != '\0' && *c != ']' ) {
+ c++;
}
- }
-
- host_size = i;
-
- if( ( i < max ) && ( in[i] == ':' ) ) {
- begin_port = i + 1;
- //convert port
- if( !( hostport_size = parse_port( max - begin_port,
- &in[begin_port],
- &out->IPv4address.sin_port ) ) )
- {
+ if( *c == '\0' ) {
+ // did not find closing bracket.
return UPNP_E_INVALID_URL;
}
- hostport_size += begin_port;
- } else
- hostport_size = host_size;
-
- //convert to temporary null terminated string
- temp_host_name = ( char * )malloc( host_size + 1 );
-
- if( temp_host_name == NULL )
- return UPNP_E_OUTOF_MEMORY;
-
- memcpy( temp_host_name, in, host_size );
- temp_host_name[host_size] = '\0';
-
- //check to see if host name is an ipv4 address
- if( ( last_dot != -1 ) && ( last_dot + 1 < host_size )
- && ( isdigit( temp_host_name[last_dot + 1] ) ) ) {
- //must be ipv4 address
-
- errcode = inet_pton( AF_INET,
- temp_host_name, &out->IPv4address.sin_addr );
- if( errcode == 1 ) {
- out->IPv4address.sin_family = AF_INET;
- } else {
- out->IPv4address.sin_addr.s_addr = 0;
- out->IPv4address.sin_family = AF_INET;
- free( temp_host_name );
- temp_host_name = NULL;
- return UPNP_E_INVALID_URL;
+ // NULL terminate the srvname and then increment c.
+ *c++ = '\0'; // overwrite the ']'
+ if( *c == ':' ) {
+ has_port = 1;
+ c++;
}
- } else {
- int errCode = 0;
+ af = AF_INET6;
+ }
+ else {
+ // IPv4 address -OR- host name.
+ srvname = c;
+ while( (*c != ':') && (*c != '/') && ( (isalnum(*c)) || (*c == '.') || (*c == '-') ) ) {
+ if( *c == '.' )
+ last_dot = c;
+ c++;
+ }
+ has_port = (*c == ':') ? 1 : 0;
+ // NULL terminate the srvname
+ *c = '\0';
+ if( has_port == 1 )
+ c++;
- //call gethostbyname_r (reentrant form of gethostbyname)
- // TODO: Use autoconf to discover this rather than the
- // platform-specific stuff below
-#if defined(WIN32) || defined(__CYGWIN__)
- h = gethostbyname(temp_host_name);
-#elif defined(SPARC_SOLARIS)
- errCode = gethostbyname_r(
- temp_host_name,
- &h,
- temp_hostbyname_buff,
- BUFFER_SIZE, &errcode );
-#elif defined(__FreeBSD__) && __FreeBSD_version < 601103
- h = lwres_gethostbyname_r(
- temp_host_name,
- &h_buf,
- temp_hostbyname_buff,
- BUFFER_SIZE, &errcode );
- if ( h == NULL ) {
- errCode = 1;
+ if( last_dot != NULL && isdigit(*(last_dot+1)) ) {
+ // Must be an IPv4 address.
+ af = AF_INET;
}
-#elif defined(__OSX__) || defined(__APPLE__)
- h = gethostbyname(temp_host_name);
- if ( h == NULL ) {
- errCode = 1;
- }
-#elif defined(__linux__)
- errCode = gethostbyname_r(
- temp_host_name,
- &h_buf,
- temp_hostbyname_buff,
- BUFFER_SIZE, &h, &errcode );
-#else
- {
- struct addrinfo hints, *res, *res0;
+ else {
+ // Must be a host name.
+ struct addrinfo hints, *res, *res0;
- h = NULL;
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = PF_INET;
- hints.ai_socktype = SOCK_STREAM;
- errCode = getaddrinfo(temp_host_name, "http", &hints, &res0);
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
- if (!errCode) {
- for (res = res0; res; res = res->ai_next) {
- if (res->ai_family == PF_INET &&
- res->ai_addr->sa_family == AF_INET)
- {
- h = &h_buf;
- h->h_addrtype = res->ai_addr->sa_family;
- h->h_length = 4;
- h->h_addr = (void *) temp_hostbyname_buff;
- *(struct in_addr *)h->h_addr =
- ((struct sockaddr_in *)res->ai_addr)->sin_addr;
+ ret = getaddrinfo(srvname, NULL, &hints, &res0);
+ if( ret == 0 ) {
+ for (res = res0; res; res = res->ai_next) {
+ if( res->ai_family == AF_INET ||
+ res->ai_family == AF_INET6 ) {
+ // Found a valid IPv4 or IPv6 address.
+ memcpy( &out->IPaddress, res->ai_addr,
+ res->ai_addrlen );
break;
+ }
}
- }
- freeaddrinfo(res0);
- }
- }
-#endif
- if( errCode == 0 ) {
- if( h ) {
- if( ( h->h_addrtype == AF_INET ) && ( h->h_length == 4 ) ) {
- out->IPv4address.sin_addr =
- ( *( struct in_addr * )h->h_addr );
- out->IPv4address.sin_family = AF_INET;
+ freeaddrinfo(res0);
+ if( res == NULL ) {
+ // Didn't find an AF_INET or AF_INET6 address.
+ return UPNP_E_INVALID_URL;
}
}
- } else {
- out->IPv4address.sin_addr.s_addr = 0;
- out->IPv4address.sin_family = AF_INET;
- free( temp_host_name );
- temp_host_name = NULL;
+ else {
+ // getaddrinfo failed.
+ return UPNP_E_INVALID_URL;
+ }
+ }
+ }
+
+ // Check if a port is specified.
+ if( has_port == 1 ) {
+ // Port is specified.
+ srvport = c;
+ while( *c != '\0' && isdigit(*c) ) {
+ c++;
+ }
+ port = (unsigned short int)atoi(srvport);
+ if( port == 0 ) {
+ // Bad port number.
return UPNP_E_INVALID_URL;
}
}
+ else {
+ // Port was not specified, use default port.
+ port = 80;
+ }
- if( temp_host_name ) {
- free( temp_host_name );
- temp_host_name = NULL;
+ // The length of the host and port string can be calculated by
+ // subtracting pointers.
+ hostport_size = (int)(c - workbuf);
+
+ // Fill in the 'out' information.
+ if( af == AF_INET ) {
+ sai4->sin_family = AF_INET;
+ sai4->sin_port = htons(port);
+ ret = inet_pton(AF_INET, srvname, &sai4->sin_addr);
}
+ else if( af == AF_INET6 ) {
+ sai6->sin6_family = AF_INET6;
+ sai6->sin6_port = htons(port);
+ sai6->sin6_scope_id = gIF_INDEX;
+ ret = inet_pton(AF_INET6, srvname, &sai6->sin6_addr);
+ } else {
+ // IP address was set by the hostname (getaddrinfo).
+ // Override port:
+ if( out->IPaddress.ss_family == AF_INET )
+ sai4->sin_port = htons(port);
+ else
+ sai6->sin6_port = htons(port);
+ ret = 1;
+ }
+ // Check if address was converted successfully.
+ if( ret <= 0 ) {
+ return UPNP_E_INVALID_URL;
+ }
+
out->text.size = hostport_size;
out->text.buff = in;
return hostport_size;
-
}
/************************************************************************
@@ -1065,10 +1029,7 @@
return begin_path;
} else {
- out->hostport.IPv4address.sin_port = 0;
- out->hostport.IPv4address.sin_addr.s_addr = 0;
- out->hostport.text.size = 0;
- out->hostport.text.buff = 0;
+ memset( &out->hostport, 0, sizeof(out->hostport) );
begin_path = begin_hostport;
}
Modified: branches/branch-ipv6/upnp/src/inc/http_client.h
===================================================================
--- branches/branch-ipv6/upnp/src/inc/http_client.h 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/src/inc/http_client.h 2008-04-30 14:17:48 UTC (rev 357)
@@ -106,7 +106,7 @@
//the full string representation
typedef struct HOSTPORT {
token text; //full host port
- struct sockaddr_in IPv4address; //Network Byte Order
+ struct sockaddr_storage IPaddress; //Network Byte Order
} hostport_type;
//Represents a URI
Modified: branches/branch-ipv6/upnp/src/inc/miniserver.h
===================================================================
--- branches/branch-ipv6/upnp/src/inc/miniserver.h 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/src/inc/miniserver.h 2008-04-30 14:17:48 UTC (rev 357)
@@ -42,17 +42,21 @@
typedef struct MServerSockArray {
/* socket for listening for miniserver requests */
- int miniServerSock;
+ SOCKET miniServerSock4;
+ SOCKET miniServerSock6;
/* socket for stopping miniserver */
- int miniServerStopSock;
+ SOCKET miniServerStopSock;
/* socket for incoming advertisments and search requests */
- int ssdpSock;
+ SOCKET ssdpSock4;
+ SOCKET ssdpSock6;
- int stopPort;
- int miniServerPort;
+ SOCKET stopPort;
+ SOCKET miniServerPort4;
+ SOCKET miniServerPort6;
/* socket for sending search requests and receiving search replies */
- CLIENTONLY(int ssdpReqSock;)
+ CLIENTONLY(SOCKET ssdpReqSock4;)
+ CLIENTONLY(SOCKET ssdpReqSock6;)
} MiniServerSockArray;
@@ -110,8 +114,10 @@
* Function: StartMiniServer
*
* Parameters:
- * unsigned short listen_port ; Port on which the server listens for
- * incoming connections
+ * IN OUT unsigned short *listen_port4 ; Port on which the server
+ * listens for incoming IPv4 connections.
+ * IN OUT unsigned short *listen_port6 ; Port on which the server
+ * listens for incoming IPv6 connections.
*
* Description: Initialize the sockets functionality for the
* Miniserver. Initialize a thread pool job to run the MiniServer
@@ -122,10 +128,11 @@
* allowed delay aborts the attempt to launch the MiniServer.
*
* Return: int;
- * Actual port socket is bound to - On Success:
- * A negative number UPNP_E_XXX - On Error
+ * On success: UPNP_E_SUCCESS
+ * On error: PNP_E_XXX
************************************************************************/
-int StartMiniServer( unsigned short listen_port );
+int StartMiniServer( IN OUT unsigned short* listen_port4,
+ IN OUT unsigned short* listen_port6 );
/************************************************************************
* Function: StopMiniServer
Modified: branches/branch-ipv6/upnp/src/inc/sock.h
===================================================================
--- branches/branch-ipv6/upnp/src/inc/sock.h 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/src/inc/sock.h 2008-04-30 14:17:48 UTC (rev 357)
@@ -48,11 +48,10 @@
typedef struct
{
- int socket; // handle/descriptor to a socket
+ SOCKET socket; // handle/descriptor to a socket
// the following two fields are filled only in incoming requests;
- struct in_addr foreign_ip_addr;
- unsigned short foreign_ip_port;
+ struct sockaddr_storage foreign_sockaddr;
} SOCKINFO;
@@ -65,7 +64,7 @@
*
* Parameters :
* OUT SOCKINFO* info ; Socket Information Object
-* IN int sockfd ; Socket Descriptor
+* IN SOCKET sockfd ; Socket Descriptor
*
* Description : Assign the passed in socket descriptor to socket
* descriptor in the SOCKINFO structure.
@@ -76,16 +75,15 @@
* UPNP_E_SOCKET_ERROR
* Note :
************************************************************************/
-int sock_init( OUT SOCKINFO* info, IN int sockfd );
+int sock_init( OUT SOCKINFO* info, IN SOCKET sockfd );
/************************************************************************
* Function : sock_init_with_ip
*
* Parameters :
* OUT SOCKINFO* info ; Socket Information Object
-* IN int sockfd ; Socket Descriptor
-* IN struct in_addr foreign_ip_addr ; Remote IP Address
-* IN unsigned short foreign_ip_port ; Remote Port number
+* IN SOCKET sockfd ; Socket Descriptor
+* IN struct sockaddr* foreign_sockaddr; Remote socket address
*
* Description : Calls the sock_init function and assigns the passed in
* IP address and port to the IP address and port in the SOCKINFO
@@ -98,8 +96,8 @@
*
* Note :
************************************************************************/
-int sock_init_with_ip( OUT SOCKINFO* info, IN int sockfd,
- IN struct in_addr foreign_ip_addr, IN unsigned short foreign_ip_port );
+int sock_init_with_ip( OUT SOCKINFO* info, IN SOCKET sockfd,
+ IN struct sockaddr* foreign_sockaddr );
/************************************************************************
* Function : sock_read
@@ -162,7 +160,7 @@
*
* Note :
************************************************************************/
-int sock_destroy( INOUT SOCKINFO* info,int );
+int sock_destroy( INOUT SOCKINFO* info, int );
#ifdef __cplusplus
} // #extern "C"
Modified: branches/branch-ipv6/upnp/src/inc/ssdplib.h
===================================================================
--- branches/branch-ipv6/upnp/src/inc/ssdplib.h 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/src/inc/ssdplib.h 2008-04-30 14:17:48 UTC (rev 357)
@@ -78,6 +78,7 @@
//Constant
#define BUFSIZE 2500
#define SSDP_IP "239.255.255.250"
+#define SSDP_IPV6_LINKLOCAL "FF02::C"
#define SSDP_PORT 1900
#define NUM_TRY 3
#define NUM_COPY 1
@@ -121,7 +122,7 @@
char Os[LINE_SIZE];
char Ext[LINE_SIZE];
char Date[LINE_SIZE];
- struct sockaddr_in * DestAddr;
+ struct sockaddr * DestAddr;
void * Cookie;
} Event;
@@ -143,7 +144,7 @@
int Mx;
void * Cookie;
char * Data;
- struct sockaddr_in DestAddr;
+ struct sockaddr_storage DestAddr;
}ThreadData;
@@ -151,7 +152,7 @@
{
int MaxAge;
UpnpDevice_Handle handle;
- struct sockaddr_in dest_addr;
+ struct sockaddr_storage dest_addr;
SsdpEvent event;
}SsdpSearchReply;
@@ -168,13 +169,14 @@
typedef struct
{
http_parser_t parser;
- struct sockaddr_in dest_addr;
+ struct sockaddr_storage dest_addr;
} ssdp_thread_data;
/* globals */
-CLIENTONLY(extern SOCKET gSsdpReqSocket;);
+CLIENTONLY(extern SOCKET gSsdpReqSocket4;);
+CLIENTONLY(extern SOCKET gSsdpReqSocket6;);
typedef int (*ParserFun)(char *, Event *);
@@ -214,11 +216,11 @@
#ifdef INCLUDE_DEVICE_APIS
void ssdp_handle_device_request(
IN http_message_t* hmsg,
- IN struct sockaddr_in* dest_addr );
+ IN struct sockaddr* dest_addr );
#else
static inline void ssdp_handle_device_request(
IN http_message_t* hmsg,
- IN struct sockaddr_in* dest_addr ) {}
+ IN struct sockaddr* dest_addr ) {}
#endif
/************************************************************************
@@ -226,7 +228,7 @@
*
* Parameters:
* IN http_message_t* hmsg: SSDP message from the device
-* IN struct sockaddr_in* dest_addr: Address of the device
+* IN struct sockaddr* 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.
@@ -243,7 +245,7 @@
***************************************************************************/
void ssdp_handle_ctrlpt_msg(
IN http_message_t* hmsg,
- IN struct sockaddr_in* dest_addr,
+ IN struct sockaddr* dest_addr,
IN xboolean timeout,
IN void* cookie );
@@ -356,6 +358,7 @@
* IN char *Udn :
* IN char *Location: Location URL.
* IN int Duration : Service duration in sec.
+* IN int AddressFamily: Device address family.
*
* Description:
* This function creates the device advertisement request based on
@@ -369,7 +372,8 @@
IN int RootDev,
IN char *Udn,
IN char *Location,
- IN int Duration);
+ IN int Duration,
+ IN int AddressFamily );
/************************************************************************
@@ -382,6 +386,7 @@
* IN char *_Server:
* IN char *Location: Location URL
* IN int Duration :Device duration in sec.
+* IN int AddressFamily: Device address family.
*
* Description:
* This function creates a HTTP device shutdown request packet
@@ -396,13 +401,14 @@
IN char *Udn,
IN char *_Server,
IN char *Location,
- IN int Duration);
+ IN int Duration,
+ IN int AddressFamily );
/************************************************************************
* Function : DeviceReply
*
* Parameters:
-* IN struct sockaddr_in * DestAddr:destination IP address.
+* IN struct sockaddr * DestAddr:destination IP address.
* IN char *DevType: Device type
* IN int RootDev: 1 means root device 0 means embedded device.
* IN char *Udn: Device UDN
@@ -417,17 +423,19 @@
* UPNP_E_SUCCESS if successful else appropriate error
***************************************************************************/
int DeviceReply(
- IN struct sockaddr_in * DestAddr,
+ IN struct sockaddr * DestAddr,
IN char *DevType,
IN int RootDev,
IN char *Udn,
- IN char *Location, IN int Duration);
+ IN char *Location,
+ IN int Duration
+);
/************************************************************************
* Function : SendReply
*
* Parameters:
-* IN struct sockaddr_in * DestAddr:destination IP address.
+* IN struct sockaddr * DestAddr:destination IP address.
* IN char *DevType: Device type
* IN int RootDev: 1 means root device 0 means embedded device.
* IN char * Udn: Device UDN
@@ -444,7 +452,7 @@
* UPNP_E_SUCCESS if successful else appropriate error
***************************************************************************/
int SendReply(
- IN struct sockaddr_in * DestAddr,
+ IN struct sockaddr * DestAddr,
IN char *DevType,
IN int RootDev,
IN char *Udn,
@@ -460,6 +468,7 @@
* IN char *ServType: Service Type.
* IN char * Location: Location of Device description document.
* IN int Duration :Life time of this device.
+* IN int AddressFamily: Device address family
*
* Description:
* This function creates the advertisement packet based
@@ -472,13 +481,14 @@
IN char *Udn,
IN char *ServType,
IN char *Location,
- IN int Duration);
+ IN int Duration,
+ IN int AddressFamily);
/************************************************************************
* Function : ServiceReply
*
* Parameters:
-* IN struct sockaddr_in *DestAddr:
+* IN struct sockaddr *DestAddr:
* IN char *Udn: Device UDN
* IN char *ServType: Service Type.
* IN char *Server: Not used
@@ -493,7 +503,7 @@
* UPNP_E_SUCCESS if successful else appropriate error
***************************************************************************/
int ServiceReply(
- IN struct sockaddr_in *DestAddr,
+ IN struct sockaddr *DestAddr,
IN char *ServType,
IN char *Udn,
IN char *Location,
@@ -507,6 +517,7 @@
* IN char *ServType: Service Type.
* IN char *Location: Location of Device description document.
* IN int Duration :Service duration in sec.
+* IN int AddressFamily: Device address family
*
* Description:
* This function creates a HTTP service shutdown request packet
@@ -519,7 +530,8 @@
IN char *Udn,
IN char *ServType,
IN char *Location,
- IN int Duration);
+ IN int Duration,
+ IN int AddressFamily);
/************************************************************************
@@ -546,7 +558,7 @@
* 1 = Send Advertisement
* IN UpnpDevice_Handle Hnd: Device handle
* IN enum SsdpSearchType SearchType:Search type for sending replies
-* IN struct sockaddr_in *DestAddr:Destination address
+* IN struct sockaddr *DestAddr:Destination address
* IN char *DeviceType:Device type
* IN char *DeviceUDN:Device UDN
* IN char *ServiceType:Service type
@@ -562,7 +574,7 @@
IN int AdFlag,
IN UpnpDevice_Handle Hnd,
IN enum SsdpSearchType SearchType,
- IN struct sockaddr_in *DestAddr,
+ IN struct sockaddr *DestAddr,
IN char *DeviceType,
IN char *DeviceUDN,
IN char *ServiceType, int Exp);
Modified: branches/branch-ipv6/upnp/src/inc/upnpapi.h
===================================================================
--- branches/branch-ipv6/upnp/src/inc/upnpapi.h 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/src/inc/upnpapi.h 2008-04-30 14:17:48 UTC (rev 357)
@@ -84,6 +84,7 @@
//URL information
int MaxSubscriptions;
int MaxSubscriptionTimeOut;
+ int DeviceAf; // Address family: AF_INET or AF_INET6
#endif
// Client only
@@ -116,8 +117,9 @@
Upnp_Handle_Type GetClientHandleInfo(int *client_handle_out,
struct Handle_Info **HndInfo);
-Upnp_Handle_Type GetDeviceHandleInfo(int *device_handle_out,
- struct Handle_Info **HndInfo);
+Upnp_Handle_Type GetDeviceHandleInfo( const int AddressFamily,
+ int *device_handle_out,
+ struct Handle_Info **HndInfo);
extern char gIF_NAME[LINE_SIZE];
@@ -125,8 +127,11 @@
extern char gIF_IPV6[65]; // INET6_ADDRSTRLEN
extern int gIF_INDEX;
-extern unsigned short LOCAL_PORT;
+extern unsigned short LOCAL_PORT_V4;
+extern unsigned short LOCAL_PORT_V6;
+extern Upnp_SID gUpnpSdkNLSuuid; // NLS uuid.
+
extern TimerThread gTimerThread;
extern ThreadPool gRecvThreadPool;
extern ThreadPool gSendThreadPool;
Modified: branches/branch-ipv6/upnp/src/inc/uri.h
===================================================================
--- branches/branch-ipv6/upnp/src/inc/uri.h 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/src/inc/uri.h 2008-04-30 14:17:48 UTC (rev 357)
@@ -95,7 +95,7 @@
* text is a token pointing to the full string representation */
typedef struct HOSTPORT {
token text; //full host port
- struct sockaddr_in IPv4address; //Network Byte Order
+ struct sockaddr_storage IPaddress; //Network Byte Order
} hostport_type;
/* Represents a URI used in parse_uri and elsewhere */
Modified: branches/branch-ipv6/upnp/src/inc/urlconfig.h
===================================================================
--- branches/branch-ipv6/upnp/src/inc/urlconfig.h 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/src/inc/urlconfig.h 2008-04-30 14:17:48 UTC (rev 357)
@@ -50,7 +50,7 @@
*
* Parameters :
* INOUT IXML_Document *doc ; IXML Description document
-* IN const struct sockaddr_in* serverAddr ; socket address object
+* IN const struct sockaddr* serverAddr ; socket address object
* providing the IP address and port information
* IN const char* alias ; string containing the alias
* IN time_t last_modified ; time when the XML document was
@@ -70,7 +70,7 @@
* Note :
****************************************************************************/
int configure_urlbase( INOUT IXML_Document *doc,
- IN const struct sockaddr_in* serverAddr,
+ IN const struct sockaddr* serverAddr,
IN const char* alias,
IN time_t last_modified,
OUT char docURL[LINE_SIZE] );
Modified: branches/branch-ipv6/upnp/src/soap/soap_device.c
===================================================================
--- branches/branch-ipv6/upnp/src/soap/soap_device.c 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/src/soap/soap_device.c 2008-04-30 14:17:48 UTC (rev 357)
@@ -589,6 +589,7 @@
get_device_info( IN http_message_t * request,
IN int isQuery,
IN IXML_Document * actionDoc,
+ IN int AddressFamily,
OUT char device_udn[LINE_SIZE],
OUT char service_id[LINE_SIZE],
OUT Upnp_FunPtr * callback,
@@ -609,7 +610,8 @@
HandleLock();
- if( GetDeviceHandleInfo( &device_hnd, &device_info ) != HND_DEVICE ) {
+ if( GetDeviceHandleInfo( AddressFamily,
+ &device_hnd, &device_info ) != HND_DEVICE ) {
goto error_handler;
}
@@ -859,9 +861,9 @@
return;
}
// get info for event
- if( get_device_info( request, 1, xml_doc, variable.DevUDN,
- variable.ServiceID,
- &soap_event_callback, &cookie ) != 0 ) {
+ if( get_device_info( request, 1, xml_doc,
+ info->foreign_sockaddr.ss_family, variable.DevUDN,
+ variable.ServiceID, &soap_event_callback, &cookie ) != 0 ) {
send_error_response( info, SOAP_INVALID_VAR,
Soap_Invalid_Var, request );
return;
@@ -871,7 +873,7 @@
variable.ErrCode = UPNP_E_SUCCESS;
namecopy( variable.StateVarName, var_name );
variable.CurrentVal = NULL;
- variable.CtrlPtIPAddr = info->foreign_ip_addr;
+ memcpy( &variable.CtrlPtSockaddr, &info->foreign_sockaddr, sizeof(variable.CtrlPtSockaddr) );
// send event
soap_event_callback( UPNP_CONTROL_GET_VAR_REQUEST, &variable, cookie );
@@ -951,9 +953,9 @@
goto error_handler;
}
// get device info for action event
- err_code = get_device_info( request, 0, xml_doc, action.DevUDN,
- action.ServiceID, &soap_event_callback,
- &cookie );
+ err_code = get_device_info( request, 0, xml_doc,
+ info->foreign_sockaddr.ss_family, action.DevUDN,
+ action.ServiceID, &soap_event_callback, &cookie );
if( err_code != UPNP_E_SUCCESS ) {
goto error_handler;
@@ -964,7 +966,7 @@
action.ActionRequest = resp_node;
action.ActionResult = NULL;
action.ErrCode = UPNP_E_SUCCESS;
- action.CtrlPtIPAddr = info->foreign_ip_addr;
+ memcpy( &action.CtrlPtSockaddr, &info->foreign_sockaddr, sizeof(action.CtrlPtSockaddr));
UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
"Calling Callback\n" );
Modified: branches/branch-ipv6/upnp/src/ssdp/ssdp_ctrlpt.c
===================================================================
--- branches/branch-ipv6/upnp/src/ssdp/ssdp_ctrlpt.c 2008-04-29 18:10:17 UTC (rev 356)
+++ branches/branch-ipv6/upnp/src/ssdp/ssdp_ctrlpt.c 2008-04-30 14:17:48 UTC (rev 357)
@@ -80,7 +80,7 @@
*
* Parameters:
* IN http_message_t* hmsg: SSDP message from the device
-* IN struct sockaddr_in* dest_addr: Address of the device
+* IN struct sockaddr* 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.
@@ -97,7 +97,7 @@
***************************************************************************/
void
ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg,
- IN struct sockaddr_in *dest_addr,
+ IN struct sockaddr *dest_addr,
@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|