Merged Charles Nepveu's IPv6 work. libupnp now is IPv6 enabled.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@358 119443c7-1b9e-41f8-b6fc-b9c35fce742c
This commit is contained in:
parent
4f2075b7c9
commit
2e4a96f034
@ -2,6 +2,9 @@
|
|||||||
Version 1.8.0
|
Version 1.8.0
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
|
|
||||||
|
2008-05-02 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
||||||
|
* Merged Charles Nepveu's IPv6 work. libupnp now is IPv6 enabled.
|
||||||
|
|
||||||
2008-02-06 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
2008-02-06 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
||||||
* Breaking API so that we now hide internal data structures.
|
* Breaking API so that we now hide internal data structures.
|
||||||
|
|
||||||
|
4
TODO
4
TODO
@ -18,6 +18,10 @@ http://sourceforge.net/tracker/?group_id=7189&atid=307189
|
|||||||
|
|
||||||
- make API clean for large files and 64 bits
|
- 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
|
To Be Decided
|
||||||
=============
|
=============
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
Version="8.00"
|
Version="8.00"
|
||||||
Name="libupnp"
|
Name="libupnp"
|
||||||
ProjectGUID="{6227F51A-1498-4C4A-B213-F6FDED605125}"
|
ProjectGUID="{6227F51A-1498-4C4A-B213-F6FDED605125}"
|
||||||
|
RootNamespace="libupnp"
|
||||||
>
|
>
|
||||||
<Platforms>
|
<Platforms>
|
||||||
<Platform
|
<Platform
|
||||||
@ -49,7 +50,7 @@
|
|||||||
Optimization="2"
|
Optimization="2"
|
||||||
InlineFunctionExpansion="1"
|
InlineFunctionExpansion="1"
|
||||||
AdditionalIncludeDirectories="..\..\pthreads\include,..\ixml\src\inc,..\ixml\inc,..\threadutil\inc,..\upnp\inc,..\upnp\src\inc,.\inc"
|
AdditionalIncludeDirectories="..\..\pthreads\include,..\ixml\src\inc,..\ixml\inc,..\threadutil\inc,..\upnp\inc,..\upnp\src\inc,.\inc"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBUPNP_EXPORTS;PTW32_STATIC_LIB;UPNP_STATIC_LIB;UPNP_USE_MSVCPP"
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBUPNP_EXPORTS;PTW32_STATIC_LIB;UPNP_STATIC_LIB;UPNP_USE_MSVCPP;_CRT_SECURE_NO_WARNINGS"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
@ -74,7 +75,7 @@
|
|||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\..\pthreads\lib\pthreadvc2.lib ws2_32.lib"
|
AdditionalDependencies="odbc32.lib odbccp32.lib ..\..\pthreads\lib\pthreadvc2.lib ws2_32.lib iphlpapi.lib"
|
||||||
OutputFile=".\Release/libupnp.dll"
|
OutputFile=".\Release/libupnp.dll"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
SuppressStartupBanner="true"
|
SuppressStartupBanner="true"
|
||||||
@ -144,7 +145,7 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..\..\pthreads\include;..\..\ixml\src\inc;..\..\ixml\inc;..\..\threadutil\inc;..\..\upnp\inc;..\..\upnp\src\inc;..\inc;..\msvc"
|
AdditionalIncludeDirectories="..\..\pthreads\include;..\..\ixml\src\inc;..\..\ixml\inc;..\..\threadutil\inc;..\..\upnp\inc;..\..\upnp\src\inc;..\inc;..\msvc"
|
||||||
PreprocessorDefinitions="DEBUG;WIN32;_WINDOWS;_USRDLL;LIBUPNP_EXPORTS;UPNP_USE_MSVCPP"
|
PreprocessorDefinitions="DEBUG;WIN32;_WINDOWS;_USRDLL;LIBUPNP_EXPORTS;UPNP_USE_MSVCPP;_CRT_SECURE_NO_WARNINGS"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
@ -170,7 +171,7 @@
|
|||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\..\pthreads\lib\pthreadvc2.lib ws2_32.lib"
|
AdditionalDependencies="odbc32.lib odbccp32.lib ..\..\pthreads\lib\pthreadvc2.lib ws2_32.lib iphlpapi.lib"
|
||||||
OutputFile="$(OutDir)\libupnp.dll"
|
OutputFile="$(OutDir)\libupnp.dll"
|
||||||
LinkIncremental="2"
|
LinkIncremental="2"
|
||||||
SuppressStartupBanner="true"
|
SuppressStartupBanner="true"
|
||||||
@ -503,6 +504,10 @@
|
|||||||
RelativePath="..\..\upnp\src\inc\unixutil.h"
|
RelativePath="..\..\upnp\src\inc\unixutil.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\upnp\inc\upnp.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\upnp\src\inc\upnp_timeout.h"
|
RelativePath="..\..\upnp\src\inc\upnp_timeout.h"
|
||||||
>
|
>
|
||||||
|
@ -149,7 +149,7 @@ dnl # "current:revision:age"
|
|||||||
dnl #
|
dnl #
|
||||||
dnl # - Code has changed in upnp
|
dnl # - Code has changed in upnp
|
||||||
dnl # revision: 5 -> 6
|
dnl # revision: 5 -> 6
|
||||||
dnl # - Interface has changed in upnp
|
dnl # - Interfaces have been changed, added and removed in upnp
|
||||||
dnl # current: 3 -> 4
|
dnl # current: 3 -> 4
|
||||||
dnl # revision: 6 -> 0
|
dnl # revision: 6 -> 0
|
||||||
dnl # - Interface has been removed in upnp
|
dnl # - Interface has been removed in upnp
|
||||||
|
@ -69,8 +69,8 @@ IXML_Document *UpnpActionRequest_get_ActionResult(const UpnpActionRequest *p);
|
|||||||
void UpnpActionRequest_set_ActionResult(UpnpActionRequest *p, IXML_Document *d);
|
void UpnpActionRequest_set_ActionResult(UpnpActionRequest *p, IXML_Document *d);
|
||||||
|
|
||||||
/** IP address of the control point requesting this action */
|
/** IP address of the control point requesting this action */
|
||||||
struct in_addr *UpnpActionRequest_get_CtrlPtIPAddr(const UpnpActionRequest *p);
|
struct sockaddr_storage *UpnpActionRequest_get_CtrlPtIPAddr(const UpnpActionRequest *p);
|
||||||
void UpnpActionRequest_set_CtrlPtIPAddr(UpnpActionRequest *p, struct in_addr *ia);
|
void UpnpActionRequest_set_CtrlPtIPAddr(UpnpActionRequest *p, struct sockaddr_storage *ia);
|
||||||
|
|
||||||
/** The DOM document containing the information from the SOAP header */
|
/** The DOM document containing the information from the SOAP header */
|
||||||
IXML_Document *UpnpActionRequest_get_SoapHeader(const UpnpActionRequest *p);
|
IXML_Document *UpnpActionRequest_get_SoapHeader(const UpnpActionRequest *p);
|
||||||
|
@ -83,8 +83,8 @@ void UpnpDiscovery_strcpy_Ext(UpnpDiscovery *p, const char *s);
|
|||||||
void UpnpDiscovery_strncpy_Ext(UpnpDiscovery *p, const char *s, int n);
|
void UpnpDiscovery_strncpy_Ext(UpnpDiscovery *p, const char *s, int n);
|
||||||
|
|
||||||
/** The host address of the device responding to the search. */
|
/** The host address of the device responding to the search. */
|
||||||
struct sockaddr_in *UpnpDiscovery_get_DestAddr(const UpnpDiscovery *p);
|
struct sockaddr *UpnpDiscovery_get_DestAddr(const UpnpDiscovery *p);
|
||||||
void UpnpDiscovery_set_DestAddr(UpnpDiscovery *p, struct sockaddr_in *sa);
|
void UpnpDiscovery_set_DestAddr(UpnpDiscovery *p, struct sockaddr *sa);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -62,8 +62,8 @@ void UpnpStateVarRequest_set_StateVarName(UpnpStateVarRequest *p, const UpnpStri
|
|||||||
void UpnpStateVarRequest_strcpy_StateVarName(UpnpStateVarRequest *p, const char *s);
|
void UpnpStateVarRequest_strcpy_StateVarName(UpnpStateVarRequest *p, const char *s);
|
||||||
|
|
||||||
/** IP address of sender requesting the state variable. */
|
/** IP address of sender requesting the state variable. */
|
||||||
struct in_addr *UpnpStateVarRequest_get_CtrlPtIPAddr(const UpnpStateVarRequest *p);
|
struct sockaddr_storage *UpnpStateVarRequest_get_CtrlPtIPAddr(const UpnpStateVarRequest *p);
|
||||||
void UpnpStateVarRequest_set_CtrlPtIPAddr(UpnpStateVarRequest *p, struct in_addr *ia);
|
void UpnpStateVarRequest_set_CtrlPtIPAddr(UpnpStateVarRequest *p, struct sockaddr_storage *ia);
|
||||||
|
|
||||||
/** The current value of the variable. This needs to be allocated by
|
/** The current value of the variable. This needs to be allocated by
|
||||||
* the caller. When finished with it, the SDK frees this {\bf DOMString}. */
|
* the caller. When finished with it, the SDK frees this {\bf DOMString}. */
|
||||||
|
136
upnp/inc/upnp.h
136
upnp/inc/upnp.h
@ -106,13 +106,15 @@
|
|||||||
#endif
|
#endif
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#define SOCKET int
|
#define SOCKET int
|
||||||
|
#define INVALID_SOCKET (SOCKET)(~0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#else
|
#else
|
||||||
#include <winsock2.h>
|
#include <Ws2tcpip.h>
|
||||||
|
#include <iphlpapi.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -296,6 +298,15 @@
|
|||||||
#define UPNP_E_ALREADY_REGISTERED -120
|
#define UPNP_E_ALREADY_REGISTERED -120
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
|
/** @name UPNP_E_INVALID_INTERFACE [-121]
|
||||||
|
* {\tt UPNP_E_INVALID_INTERFACE} signifies that the interface provided to
|
||||||
|
* {\bf UpnpInit2} is unknown or does not have a valid IPv4 or IPv6
|
||||||
|
* address configured.
|
||||||
|
*/
|
||||||
|
/*! @{ */
|
||||||
|
#define UPNP_E_INVALID_INTERFACE -121
|
||||||
|
/*! @} */
|
||||||
|
|
||||||
/** @name UPNP_E_NETWORK_ERROR [-200]
|
/** @name UPNP_E_NETWORK_ERROR [-200]
|
||||||
* {\tt UPNP_E_NETWORK_ERROR} signifies that a network error occurred. It
|
* {\tt UPNP_E_NETWORK_ERROR} signifies that a network error occurred. It
|
||||||
* is the generic error code for network problems that are not covered under
|
* is the generic error code for network problems that are not covered under
|
||||||
@ -930,6 +941,51 @@ EXPORT_SPEC int UpnpInit(
|
|||||||
will pick an arbitrary free port. */
|
will pick an arbitrary free port. */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/*! @name Initialization and Registration */
|
||||||
|
/*! @{ */
|
||||||
|
/** Initializes the Linux SDK for UPnP Devices. This function must be called
|
||||||
|
* before any other API function can be called. It should be called
|
||||||
|
* only once. Subsequent calls to this API return a {\tt UPNP_E_INIT}
|
||||||
|
* error code.
|
||||||
|
*
|
||||||
|
* Optionally, the application can specify an interface name (in the
|
||||||
|
* case of a multi-homed configuration) and a port number to use for
|
||||||
|
* all UPnP operations. Since a port number can be used only by one
|
||||||
|
* process, multiple processes using the SDK must specify
|
||||||
|
* different port numbers.
|
||||||
|
*
|
||||||
|
* If unspecified, the SDK will use the first suitable interface and an
|
||||||
|
* arbitrary port.
|
||||||
|
*
|
||||||
|
* This call is synchronous.
|
||||||
|
*
|
||||||
|
* @return [int] An integer representing one of the following:
|
||||||
|
* \begin{itemize}
|
||||||
|
* \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
|
||||||
|
* \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist
|
||||||
|
* to initialize the SDK.
|
||||||
|
* \item {\tt UPNP_E_INIT}: The SDK is already initialized.
|
||||||
|
* \item {\tt UPNP_E_INIT_FAILED}: The SDK initialization
|
||||||
|
* failed for an unknown reason.
|
||||||
|
* \item {\tt UPNP_E_SOCKET_BIND}: An error occurred binding a socket.
|
||||||
|
* \item {\tt UPNP_E_LISTEN}: An error occurred listening to a socket.
|
||||||
|
* \item {\tt UPNP_E_OUTOF_SOCKET}: An error ocurred creating a socket.
|
||||||
|
* \item {\tt UPNP_E_INTERNAL_ERROR}: An internal error ocurred.
|
||||||
|
* \item {\tt UPNP_E_INVALID_INTERFACE}: IfName is invalid or doees not
|
||||||
|
* have a valid IPv4 or IPv6 addresss configured.
|
||||||
|
* \end{itemize} */
|
||||||
|
|
||||||
|
EXPORT_SPEC int UpnpInit2(
|
||||||
|
IN const char *IfName, /** The interface name to use by the UPnP SDK
|
||||||
|
operations. Examples: "eth0", "xl0",
|
||||||
|
"Local Area Connection", {\tt NULL} to
|
||||||
|
use the first suitable interface. */
|
||||||
|
IN unsigned short DestPort /** The destination port number to use. 0
|
||||||
|
will pick an arbitrary free port. */
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
/** Terminates the Linux SDK for UPnP Devices. This function must be the last
|
/** Terminates the Linux SDK for UPnP Devices. This function must be the last
|
||||||
* API function called. It should be called only once. Subsequent calls to
|
* API function called. It should be called only once. Subsequent calls to
|
||||||
* this API return a {\tt UPNP_E_FINISH} error code.
|
* this API return a {\tt UPNP_E_FINISH} error code.
|
||||||
@ -949,20 +1005,40 @@ EXPORT_SPEC int UpnpFinish();
|
|||||||
* returned.
|
* returned.
|
||||||
*
|
*
|
||||||
* @return [unsigned short] The port on which an internal server is
|
* @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);
|
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
|
* function can be used to retrieve the actual interface address
|
||||||
* on which device is running. If {\bf UpnpInit} has not succeeded
|
* on which device is running. If {\bf UpnpInit} has not succeeded
|
||||||
* then {\tt NULL} is returned.
|
* 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.
|
* for UPnP related requests.
|
||||||
*/
|
*/
|
||||||
EXPORT_SPEC char * UpnpGetServerIpAddress(void);
|
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
|
/** {\bf UpnpRegisterClient} registers a control point application with the
|
||||||
* SDK. A control point application cannot make any other API calls
|
* SDK. A control point application cannot make any other API calls
|
||||||
* until it registers using this function.
|
* until it registers using this function.
|
||||||
@ -1129,6 +1205,58 @@ EXPORT_SPEC int UpnpRegisterRootDevice2(
|
|||||||
the new device handle. */
|
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,
|
/** {\bf UpnpUnRegisterClient} unregisters a control point application,
|
||||||
* unsubscribing all active subscriptions. After this call, the
|
* unsubscribing all active subscriptions. After this call, the
|
||||||
* {\bf UpnpClient_Handle} is no longer valid.
|
* {\bf UpnpClient_Handle} is no longer valid.
|
||||||
|
@ -21,7 +21,7 @@ struct SUpnpActionRequest
|
|||||||
IXML_Document *m_actionRequest;
|
IXML_Document *m_actionRequest;
|
||||||
IXML_Document *m_actionResult;
|
IXML_Document *m_actionResult;
|
||||||
IXML_Document *m_soapHeader;
|
IXML_Document *m_soapHeader;
|
||||||
struct in_addr m_ctrlPtIPAddr;
|
struct sockaddr_storage m_ctrlPtIPAddr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ UpnpActionRequest *UpnpActionRequest_new()
|
|||||||
p->m_actionRequest = NULL;
|
p->m_actionRequest = NULL;
|
||||||
p->m_actionResult = NULL;
|
p->m_actionResult = NULL;
|
||||||
p->m_soapHeader = NULL;
|
p->m_soapHeader = NULL;
|
||||||
memset(&p->m_ctrlPtIPAddr, 0, sizeof (struct in_addr));
|
memset(&p->m_ctrlPtIPAddr, 0, sizeof (struct sockaddr_storage));
|
||||||
#endif
|
#endif
|
||||||
return (UpnpActionRequest *)p;
|
return (UpnpActionRequest *)p;
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ void UpnpActionRequest_delete(UpnpActionRequest *p)
|
|||||||
|
|
||||||
UpnpActionRequest_set_SoapHeader(p, NULL);
|
UpnpActionRequest_set_SoapHeader(p, NULL);
|
||||||
|
|
||||||
memset(&q->m_ctrlPtIPAddr, 0, sizeof (struct in_addr));
|
memset(&q->m_ctrlPtIPAddr, 0, sizeof (struct sockaddr_storage));
|
||||||
|
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
@ -224,13 +224,13 @@ void UpnpActionRequest_set_ActionResult(UpnpActionRequest *p, IXML_Document *d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct in_addr *UpnpActionRequest_get_CtrlPtIPAddr(const UpnpActionRequest *p)
|
struct sockaddr_storage *UpnpActionRequest_get_CtrlPtIPAddr(const UpnpActionRequest *p)
|
||||||
{
|
{
|
||||||
return &((struct SUpnpActionRequest *)p)->m_ctrlPtIPAddr;
|
return &((struct SUpnpActionRequest *)p)->m_ctrlPtIPAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void UpnpActionRequest_set_CtrlPtIPAddr(UpnpActionRequest *p, struct in_addr *ia)
|
void UpnpActionRequest_set_CtrlPtIPAddr(UpnpActionRequest *p, struct sockaddr_storage *ia)
|
||||||
{
|
{
|
||||||
((struct SUpnpActionRequest *)p)->m_ctrlPtIPAddr = *ia;
|
((struct SUpnpActionRequest *)p)->m_ctrlPtIPAddr = *ia;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ struct SUpnpDiscovery
|
|||||||
UpnpString *m_os;
|
UpnpString *m_os;
|
||||||
UpnpString *m_date;
|
UpnpString *m_date;
|
||||||
UpnpString *m_ext;
|
UpnpString *m_ext;
|
||||||
struct sockaddr_in m_destAddr;
|
struct sockaddr m_destAddr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -332,13 +332,13 @@ void UpnpDiscovery_strncpy_Ext(UpnpDiscovery *p, const char *s, int n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct sockaddr_in *UpnpDiscovery_get_DestAddr(const UpnpDiscovery *p)
|
struct sockaddr *UpnpDiscovery_get_DestAddr(const UpnpDiscovery *p)
|
||||||
{
|
{
|
||||||
return &((struct SUpnpDiscovery *)p)->m_destAddr;
|
return &((struct SUpnpDiscovery *)p)->m_destAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void UpnpDiscovery_set_DestAddr(UpnpDiscovery *p, struct sockaddr_in *sa)
|
void UpnpDiscovery_set_DestAddr(UpnpDiscovery *p, struct sockaddr *sa)
|
||||||
{
|
{
|
||||||
((struct SUpnpDiscovery *)p)->m_destAddr = *sa;
|
((struct SUpnpDiscovery *)p)->m_destAddr = *sa;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ struct SUpnpStateVarRequest
|
|||||||
UpnpString *m_devUDN;
|
UpnpString *m_devUDN;
|
||||||
UpnpString *m_serviceID;
|
UpnpString *m_serviceID;
|
||||||
UpnpString *m_stateVarName;
|
UpnpString *m_stateVarName;
|
||||||
struct in_addr m_ctrlPtIPAddr;
|
struct sockaddr_storage m_ctrlPtIPAddr;
|
||||||
DOMString m_currentVal;
|
DOMString m_currentVal;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ UpnpStateVarRequest *UpnpStateVarRequest_new()
|
|||||||
p->m_serviceID = UpnpString_new();
|
p->m_serviceID = UpnpString_new();
|
||||||
p->m_stateVarName = UpnpString_new();
|
p->m_stateVarName = UpnpString_new();
|
||||||
#if 0
|
#if 0
|
||||||
memset(&q->m_ctrlPtIPAddr, 0, sizeof (struct in_addr));
|
memset(&q->m_ctrlPtIPAddr, 0, sizeof (struct sockaddr_storage));
|
||||||
p->m_currentVal = NULL;
|
p->m_currentVal = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ void UpnpStateVarRequest_delete(UpnpStateVarRequest *p)
|
|||||||
UpnpString_delete(q->m_stateVarName);
|
UpnpString_delete(q->m_stateVarName);
|
||||||
q->m_stateVarName = NULL;
|
q->m_stateVarName = NULL;
|
||||||
|
|
||||||
memset(&q->m_ctrlPtIPAddr, 0, sizeof (struct in_addr));
|
memset(&q->m_ctrlPtIPAddr, 0, sizeof (struct sockaddr_storage));
|
||||||
|
|
||||||
ixmlFreeDOMString(q->m_currentVal);
|
ixmlFreeDOMString(q->m_currentVal);
|
||||||
q->m_currentVal = NULL;
|
q->m_currentVal = NULL;
|
||||||
@ -190,13 +190,13 @@ void UpnpStateVarRequest_strcpy_StateVarName(UpnpStateVarRequest *p, const char
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct in_addr *UpnpStateVarRequest_get_CtrlPtIPAddr(const UpnpStateVarRequest *p)
|
struct sockaddr_storage *UpnpStateVarRequest_get_CtrlPtIPAddr(const UpnpStateVarRequest *p)
|
||||||
{
|
{
|
||||||
return &((struct SUpnpStateVarRequest *)p)->m_ctrlPtIPAddr;
|
return &((struct SUpnpStateVarRequest *)p)->m_ctrlPtIPAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void UpnpStateVarRequest_set_CtrlPtIPAddr(UpnpStateVarRequest *p, struct in_addr *ia)
|
void UpnpStateVarRequest_set_CtrlPtIPAddr(UpnpStateVarRequest *p, struct sockaddr_storage *ia)
|
||||||
{
|
{
|
||||||
((struct SUpnpStateVarRequest *)p)->m_ctrlPtIPAddr = *ia;
|
((struct SUpnpStateVarRequest *)p)->m_ctrlPtIPAddr = *ia;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -325,13 +325,23 @@ static int gena_subscribe(
|
|||||||
"TIMEOUT: Second-", timeout_str );
|
"TIMEOUT: Second-", timeout_str );
|
||||||
} else {
|
} else {
|
||||||
// subscribe
|
// subscribe
|
||||||
return_code = http_MakeMessage(
|
if( dest_url.hostport.IPaddress.ss_family == AF_INET6 ) {
|
||||||
&request, 1, 1,
|
return_code = http_MakeMessage(
|
||||||
"q" "sssdsc" "sc" "sscc",
|
&request, 1, 1,
|
||||||
HTTPMETHOD_SUBSCRIBE, &dest_url,
|
"q" "sssdsc" "sc" "sscc",
|
||||||
"CALLBACK: <http://", LOCAL_HOST, ":", LOCAL_PORT, "/>",
|
HTTPMETHOD_SUBSCRIBE, &dest_url,
|
||||||
"NT: upnp:event",
|
"CALLBACK: <http://[", gIF_IPV6, "]:", LOCAL_PORT_V6, "/>",
|
||||||
"TIMEOUT: Second-", timeout_str);
|
"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) {
|
if (return_code != 0) {
|
||||||
return return_code;
|
return return_code;
|
||||||
|
@ -1352,7 +1352,8 @@ gena_process_subscription_request( IN SOCKINFO * info,
|
|||||||
HandleLock();
|
HandleLock();
|
||||||
|
|
||||||
// CURRENTLY, ONLY ONE DEVICE
|
// 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 );
|
free( event_url_path );
|
||||||
error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
|
error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
|
||||||
HandleUnlock();
|
HandleUnlock();
|
||||||
@ -1527,7 +1528,8 @@ gena_process_subscription_renewal_request( IN SOCKINFO * info,
|
|||||||
HandleLock();
|
HandleLock();
|
||||||
|
|
||||||
// CURRENTLY, ONLY SUPPORT ONE DEVICE
|
// 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 );
|
error_respond( info, HTTP_PRECONDITION_FAILED, request );
|
||||||
membuffer_destroy( &event_url_path );
|
membuffer_destroy( &event_url_path );
|
||||||
return;
|
return;
|
||||||
@ -1650,7 +1652,8 @@ gena_process_unsubscribe_request( IN SOCKINFO * info,
|
|||||||
HandleLock();
|
HandleLock();
|
||||||
|
|
||||||
// CURRENTLY, ONLY SUPPORT ONE DEVICE
|
// 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 );
|
error_respond( info, HTTP_PRECONDITION_FAILED, request );
|
||||||
membuffer_destroy( &event_url_path );
|
membuffer_destroy( &event_url_path );
|
||||||
HandleUnlock();
|
HandleUnlock();
|
||||||
|
@ -73,8 +73,7 @@
|
|||||||
|
|
||||||
struct mserv_request_t {
|
struct mserv_request_t {
|
||||||
int connfd; // connection handle
|
int connfd; // connection handle
|
||||||
struct in_addr foreign_ip_addr;
|
struct sockaddr_storage foreign_sockaddr;
|
||||||
unsigned short foreign_ip_port;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum { MSERV_IDLE, MSERV_RUNNING, MSERV_STOPPING } MiniServerState;
|
typedef enum { MSERV_IDLE, MSERV_RUNNING, MSERV_STOPPING } MiniServerState;
|
||||||
@ -272,8 +271,8 @@ handle_request( void *args )
|
|||||||
//parser_request_init( &parser ); ////LEAK_FIX_MK
|
//parser_request_init( &parser ); ////LEAK_FIX_MK
|
||||||
hmsg = &parser.msg;
|
hmsg = &parser.msg;
|
||||||
|
|
||||||
if( sock_init_with_ip( &info, connfd, request->foreign_ip_addr,
|
if( sock_init_with_ip( &info, connfd, (struct sockaddr*)&request->foreign_sockaddr )
|
||||||
request->foreign_ip_port ) != UPNP_E_SUCCESS ) {
|
!= UPNP_E_SUCCESS ) {
|
||||||
free( request );
|
free( request );
|
||||||
httpmsg_destroy( hmsg );
|
httpmsg_destroy( hmsg );
|
||||||
return;
|
return;
|
||||||
@ -317,7 +316,7 @@ handle_request( void *args )
|
|||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN int connfd - Socket Descriptor on which connection is accepted
|
* 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:
|
* Description:
|
||||||
* Initilize the thread pool to handle a request.
|
* Initilize the thread pool to handle a request.
|
||||||
@ -327,7 +326,7 @@ handle_request( void *args )
|
|||||||
************************************************************************/
|
************************************************************************/
|
||||||
static UPNP_INLINE void
|
static UPNP_INLINE void
|
||||||
schedule_request_job( IN int connfd,
|
schedule_request_job( IN int connfd,
|
||||||
IN struct sockaddr_in *clientAddr )
|
IN struct sockaddr *clientAddr )
|
||||||
{
|
{
|
||||||
struct mserv_request_t *request;
|
struct mserv_request_t *request;
|
||||||
ThreadPoolJob job;
|
ThreadPoolJob job;
|
||||||
@ -338,14 +337,13 @@ schedule_request_job( IN int connfd,
|
|||||||
if( request == NULL ) {
|
if( request == NULL ) {
|
||||||
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
|
||||||
"mserv %d: out of memory\n", connfd );
|
"mserv %d: out of memory\n", connfd );
|
||||||
shutdown( request->connfd, SD_BOTH );
|
shutdown( connfd, SD_BOTH );
|
||||||
UpnpCloseSocket( connfd );
|
UpnpCloseSocket( connfd );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
request->connfd = connfd;
|
request->connfd = connfd;
|
||||||
request->foreign_ip_addr = clientAddr->sin_addr;
|
memcpy( &request->foreign_sockaddr, clientAddr, sizeof(request->foreign_sockaddr) );
|
||||||
request->foreign_ip_port = ntohs( clientAddr->sin_port );
|
|
||||||
|
|
||||||
TPJobInit( &job, ( start_routine ) handle_request, ( void * )request );
|
TPJobInit( &job, ( start_routine ) handle_request, ( void * )request );
|
||||||
TPJobSetFreeFunction( &job, free_handle_request_arg );
|
TPJobSetFreeFunction( &job, free_handle_request_arg );
|
||||||
@ -380,28 +378,41 @@ static void
|
|||||||
RunMiniServer( MiniServerSockArray *miniSock )
|
RunMiniServer( MiniServerSockArray *miniSock )
|
||||||
{
|
{
|
||||||
char errorBuffer[ERROR_BUFFER_LEN];
|
char errorBuffer[ERROR_BUFFER_LEN];
|
||||||
struct sockaddr_in clientAddr;
|
struct sockaddr_storage clientAddr;
|
||||||
socklen_t clientLen;
|
socklen_t clientLen;
|
||||||
SOCKET connectHnd;
|
SOCKET connectHnd;
|
||||||
SOCKET miniServSock = miniSock->miniServerSock;
|
SOCKET miniServSock4 = miniSock->miniServerSock4;
|
||||||
|
SOCKET miniServSock6 = miniSock->miniServerSock6;
|
||||||
SOCKET miniServStopSock = miniSock->miniServerStopSock;
|
SOCKET miniServStopSock = miniSock->miniServerStopSock;
|
||||||
SOCKET ssdpSock = miniSock->ssdpSock;
|
SOCKET ssdpSock4 = miniSock->ssdpSock4;
|
||||||
|
SOCKET ssdpSock6 = miniSock->ssdpSock6;
|
||||||
#ifdef INCLUDE_CLIENT_APIS
|
#ifdef INCLUDE_CLIENT_APIS
|
||||||
SOCKET ssdpReqSock = miniSock->ssdpReqSock;
|
SOCKET ssdpReqSock4 = miniSock->ssdpReqSock4;
|
||||||
|
SOCKET ssdpReqSock6 = miniSock->ssdpReqSock6;
|
||||||
#endif
|
#endif
|
||||||
|
char buf_ntop[64];
|
||||||
fd_set expSet;
|
fd_set expSet;
|
||||||
fd_set rdSet;
|
fd_set rdSet;
|
||||||
unsigned int maxMiniSock;
|
unsigned int maxMiniSock = 0;
|
||||||
int byteReceived;
|
int byteReceived;
|
||||||
char requestBuf[256];
|
char requestBuf[256];
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
maxMiniSock = max( miniServSock, miniServStopSock) ;
|
if( miniServSock4 != INVALID_SOCKET )
|
||||||
maxMiniSock = max( maxMiniSock, (SOCKET)(ssdpSock) );
|
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
|
#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
|
#endif
|
||||||
|
maxMiniSock = max( maxMiniSock, miniServStopSock) ;
|
||||||
++maxMiniSock;
|
++maxMiniSock;
|
||||||
|
|
||||||
gMServState = MSERV_RUNNING;
|
gMServState = MSERV_RUNNING;
|
||||||
@ -410,11 +421,20 @@ RunMiniServer( MiniServerSockArray *miniSock )
|
|||||||
FD_ZERO( &expSet );
|
FD_ZERO( &expSet );
|
||||||
|
|
||||||
FD_SET( miniServStopSock, &expSet );
|
FD_SET( miniServStopSock, &expSet );
|
||||||
FD_SET( miniServSock, &rdSet );
|
|
||||||
FD_SET( miniServStopSock, &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
|
#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
|
#endif
|
||||||
|
|
||||||
ret = select( maxMiniSock, &rdSet, NULL, &expSet, NULL );
|
ret = select( maxMiniSock, &rdSet, NULL, &expSet, NULL );
|
||||||
@ -426,9 +446,10 @@ RunMiniServer( MiniServerSockArray *miniSock )
|
|||||||
isleep( 1 );
|
isleep( 1 );
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if( FD_ISSET( miniServSock, &rdSet ) ) {
|
if( miniServSock6 != INVALID_SOCKET &&
|
||||||
clientLen = sizeof( struct sockaddr_in );
|
FD_ISSET( miniServSock6, &rdSet ) ) {
|
||||||
connectHnd = accept( miniServSock,
|
clientLen = sizeof( clientAddr );
|
||||||
|
connectHnd = accept( miniServSock6,
|
||||||
( struct sockaddr * )&clientAddr, &clientLen );
|
( struct sockaddr * )&clientAddr, &clientLen );
|
||||||
if( connectHnd == -1 ) {
|
if( connectHnd == -1 ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
@ -436,29 +457,55 @@ RunMiniServer( MiniServerSockArray *miniSock )
|
|||||||
"miniserver: Error in accept(): %s\n", errorBuffer );
|
"miniserver: Error in accept(): %s\n", errorBuffer );
|
||||||
continue;
|
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
|
#ifdef INCLUDE_CLIENT_APIS
|
||||||
// ssdp
|
// ssdp
|
||||||
if( FD_ISSET( ssdpReqSock, &rdSet ) ) {
|
if( ssdpReqSock6 != INVALID_SOCKET &&
|
||||||
readFromSSDPSocket( ssdpReqSock );
|
FD_ISSET( ssdpReqSock6, &rdSet ) ) {
|
||||||
|
readFromSSDPSocket( ssdpReqSock6 );
|
||||||
|
}
|
||||||
|
if( ssdpReqSock4 != INVALID_SOCKET &&
|
||||||
|
FD_ISSET( ssdpReqSock4, &rdSet ) ) {
|
||||||
|
readFromSSDPSocket( ssdpReqSock4 );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if( FD_ISSET( ssdpSock, &rdSet ) ) {
|
if( ssdpSock6 != INVALID_SOCKET &&
|
||||||
readFromSSDPSocket( ssdpSock );
|
FD_ISSET( ssdpSock6, &rdSet ) ) {
|
||||||
|
readFromSSDPSocket( ssdpSock6 );
|
||||||
|
}
|
||||||
|
if( ssdpSock4 != INVALID_SOCKET &&
|
||||||
|
FD_ISSET( ssdpSock4, &rdSet ) ) {
|
||||||
|
readFromSSDPSocket( ssdpSock4 );
|
||||||
}
|
}
|
||||||
if( FD_ISSET( miniServStopSock, &rdSet ) ) {
|
if( FD_ISSET( miniServStopSock, &rdSet ) ) {
|
||||||
clientLen = sizeof( struct sockaddr_in );
|
clientLen = sizeof( clientAddr );
|
||||||
memset( (char *)&clientAddr, 0, sizeof (struct sockaddr_in) );
|
memset( (char *)&clientAddr, 0, sizeof(clientAddr) );
|
||||||
byteReceived =
|
byteReceived =
|
||||||
recvfrom( miniServStopSock, requestBuf, 25, 0,
|
recvfrom( miniServStopSock, requestBuf, 25, 0,
|
||||||
( struct sockaddr * )&clientAddr,
|
( struct sockaddr * )&clientAddr,
|
||||||
&clientLen );
|
&clientLen );
|
||||||
if( byteReceived > 0 ) {
|
if( byteReceived > 0 ) {
|
||||||
requestBuf[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__,
|
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
|
||||||
"Received response: %s From host %s \n",
|
"Received response: %s From host %s \n",
|
||||||
requestBuf, inet_ntoa( clientAddr.sin_addr ) );
|
requestBuf, buf_ntop );
|
||||||
UpnpPrintf( UPNP_PACKET, MSERV, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_PACKET, MSERV, __FILE__, __LINE__,
|
||||||
"Received multicast packet: \n %s\n",
|
"Received multicast packet: \n %s\n",
|
||||||
requestBuf );
|
requestBuf );
|
||||||
@ -470,15 +517,21 @@ RunMiniServer( MiniServerSockArray *miniSock )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shutdown( miniServSock, SD_BOTH );
|
shutdown( miniServSock4, SD_BOTH );
|
||||||
UpnpCloseSocket( miniServSock );
|
UpnpCloseSocket( miniServSock4 );
|
||||||
|
shutdown( miniServSock6, SD_BOTH );
|
||||||
|
UpnpCloseSocket( miniServSock6 );
|
||||||
shutdown( miniServStopSock, SD_BOTH );
|
shutdown( miniServStopSock, SD_BOTH );
|
||||||
UpnpCloseSocket( miniServStopSock );
|
UpnpCloseSocket( miniServStopSock );
|
||||||
shutdown( ssdpSock, SD_BOTH );
|
shutdown( ssdpSock4, SD_BOTH );
|
||||||
UpnpCloseSocket( ssdpSock );
|
UpnpCloseSocket( ssdpSock4 );
|
||||||
|
shutdown( ssdpSock6, SD_BOTH );
|
||||||
|
UpnpCloseSocket( ssdpSock6 );
|
||||||
#ifdef INCLUDE_CLIENT_APIS
|
#ifdef INCLUDE_CLIENT_APIS
|
||||||
shutdown( ssdpReqSock, SD_BOTH );
|
shutdown( ssdpReqSock4, SD_BOTH );
|
||||||
UpnpCloseSocket( ssdpReqSock );
|
UpnpCloseSocket( ssdpReqSock4 );
|
||||||
|
shutdown( ssdpReqSock6, SD_BOTH );
|
||||||
|
UpnpCloseSocket( ssdpReqSock6 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
free( miniSock );
|
free( miniSock );
|
||||||
@ -503,18 +556,22 @@ RunMiniServer( MiniServerSockArray *miniSock )
|
|||||||
static int
|
static int
|
||||||
get_port( int sockfd )
|
get_port( int sockfd )
|
||||||
{
|
{
|
||||||
struct sockaddr_in sockinfo;
|
struct sockaddr_storage sockinfo;
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
int code;
|
int code;
|
||||||
int port;
|
int port = 0;
|
||||||
|
|
||||||
len = sizeof( struct sockaddr_in );
|
len = sizeof( sockinfo );
|
||||||
code = getsockname( sockfd, ( struct sockaddr * )&sockinfo, &len );
|
code = getsockname( sockfd, ( struct sockaddr * )&sockinfo, &len );
|
||||||
if( code == -1 ) {
|
if( code == -1 ) {
|
||||||
return -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__,
|
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
|
||||||
"sockfd = %d, .... port = %d\n", sockfd, port );
|
"sockfd = %d, .... port = %d\n", sockfd, port );
|
||||||
|
|
||||||
@ -526,8 +583,10 @@ get_port( int sockfd )
|
|||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* MiniServerSockArray *out - Socket Array
|
* MiniServerSockArray *out - Socket Array
|
||||||
* unsigned short listen_port - port on which the server is
|
* unsigned short listen_port4 - port on which the server is
|
||||||
* listening for incoming connections
|
* listening for incoming IPv4 connections
|
||||||
|
* unsigned short listen_port6 - port on which the server is
|
||||||
|
* listening for incoming IPv6 connections
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Creates a STREAM socket, binds to INADDR_ANY and listens for
|
* Creates a STREAM socket, binds to INADDR_ANY and listens for
|
||||||
@ -546,31 +605,47 @@ get_port( int sockfd )
|
|||||||
************************************************************************/
|
************************************************************************/
|
||||||
int
|
int
|
||||||
get_miniserver_sockets( MiniServerSockArray * out,
|
get_miniserver_sockets( MiniServerSockArray * out,
|
||||||
unsigned short listen_port )
|
unsigned short listen_port4,
|
||||||
|
unsigned short listen_port6 )
|
||||||
{
|
{
|
||||||
char errorBuffer[ERROR_BUFFER_LEN];
|
char errorBuffer[ERROR_BUFFER_LEN];
|
||||||
struct sockaddr_in serverAddr;
|
struct sockaddr_storage __ss_v4;
|
||||||
int listenfd;
|
struct sockaddr_storage __ss_v6;
|
||||||
int success;
|
struct sockaddr_in* serverAddr4 = (struct sockaddr_in*)&__ss_v4;
|
||||||
unsigned short actual_port;
|
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 reuseaddr_on = 0;
|
||||||
int sockError = UPNP_E_SUCCESS;
|
int sockError = UPNP_E_SUCCESS;
|
||||||
int errCode = 0;
|
int errCode = 0;
|
||||||
int miniServerStopSock;
|
int miniServerStopSock;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
listenfd = socket( AF_INET, SOCK_STREAM, 0 );
|
// Create listen socket for IPv4/IPv6. An error here may indicate
|
||||||
if ( listenfd == -1 ) {
|
// that we don't have an IPv4/IPv6 stack.
|
||||||
return UPNP_E_OUTOF_SOCKET; // error creating socket
|
listenfd4 = socket( AF_INET, SOCK_STREAM, 0 );
|
||||||
|
listenfd6 = socket( AF_INET6, SOCK_STREAM, 0 );
|
||||||
|
if (listenfd4 == INVALID_SOCKET || listenfd6 == INVALID_SOCKET) {
|
||||||
|
return UPNP_E_OUTOF_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
// As per the IANA specifications for the use of ports by applications
|
// As per the IANA specifications for the use of ports by applications
|
||||||
// override the listen port passed in with the first available
|
// override the listen port passed in with the first available
|
||||||
if( listen_port < APPLICATION_LISTENING_PORT )
|
if (listen_port4 < APPLICATION_LISTENING_PORT) {
|
||||||
listen_port = APPLICATION_LISTENING_PORT;
|
listen_port4 = APPLICATION_LISTENING_PORT;
|
||||||
|
}
|
||||||
|
if (listen_port6 < APPLICATION_LISTENING_PORT) {
|
||||||
|
listen_port6 = APPLICATION_LISTENING_PORT;
|
||||||
|
}
|
||||||
|
|
||||||
memset( &serverAddr, 0, sizeof( serverAddr ) );
|
memset( &__ss_v4, 0, sizeof( __ss_v4 ) );
|
||||||
serverAddr.sin_family = AF_INET;
|
serverAddr4->sin_family = AF_INET;
|
||||||
serverAddr.sin_addr.s_addr = htonl( INADDR_ANY );
|
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
|
// Getting away with implementation of re-using address:port and instead
|
||||||
// choosing to increment port numbers.
|
// choosing to increment port numbers.
|
||||||
@ -583,95 +658,211 @@ get_miniserver_sockets( MiniServerSockArray * out,
|
|||||||
// THIS MAY CAUSE TCP TO BECOME LESS RELIABLE
|
// THIS MAY CAUSE TCP TO BECOME LESS RELIABLE
|
||||||
// HOWEVER IT HAS BEEN SUGESTED FOR TCP SERVERS
|
// HOWEVER IT HAS BEEN SUGESTED FOR TCP SERVERS
|
||||||
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
|
||||||
"mserv start: resuseaddr set\n" );
|
"get_miniserver_sockets: 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 );
|
|
||||||
|
|
||||||
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,
|
if( listenfd6 != INVALID_SOCKET ) {
|
||||||
sizeof (struct sockaddr_in) );
|
sockError = setsockopt( listenfd6, SOL_SOCKET, SO_REUSEADDR,
|
||||||
} else {
|
(const char *)&reuseaddr_on, sizeof (int) );
|
||||||
do {
|
|
||||||
serverAddr.sin_port = htons( listen_port++ );
|
|
||||||
sockError = bind( listenfd, (struct sockaddr *)&serverAddr,
|
|
||||||
sizeof (struct sockaddr_in) );
|
|
||||||
if ( sockError == -1 ) {
|
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 {
|
||||||
|
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
|
#ifdef WIN32
|
||||||
errCode = WSAGetLastError();
|
errCode = WSAGetLastError();
|
||||||
#else
|
#else
|
||||||
errCode = errno;
|
errCode = errno;
|
||||||
#endif
|
#endif
|
||||||
if( errno == EADDRINUSE ) {
|
if( errno == EADDRINUSE ) {
|
||||||
errCode = 1;
|
errCode = 1;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
errCode = 0;
|
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 ) {
|
if( listenfd6 != INVALID_SOCKET ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
do {
|
||||||
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
|
serverAddr4->sin_port = htons( listen_port6++ );
|
||||||
"mserv start: Error in bind(): %s\n", errorBuffer );
|
sockError = bind( listenfd6, (struct sockaddr *)&__ss_v4,
|
||||||
shutdown( listenfd, SD_BOTH );
|
sizeof(__ss_v4) );
|
||||||
UpnpCloseSocket( listenfd );
|
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__,
|
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
|
||||||
"mserv start: bind success\n" );
|
"get_miniserver_sockets: bind successful\n" );
|
||||||
|
|
||||||
success = listen( listenfd, SOMAXCONN );
|
if( listenfd4 != INVALID_SOCKET ) {
|
||||||
if ( success == -1 ) {
|
ret_code = listen( listenfd4, SOMAXCONN );
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
if ( ret_code == -1 ) {
|
||||||
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
"mserv start: Error in listen(): %s\n", errorBuffer );
|
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
|
||||||
shutdown( listenfd, SD_BOTH );
|
"mserv start: Error in IPv4 listen(): %s\n", errorBuffer );
|
||||||
UpnpCloseSocket( listenfd );
|
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( listenfd6 != INVALID_SOCKET ) {
|
||||||
if( actual_port <= 0 ) {
|
ret_code = listen( listenfd6, SOMAXCONN );
|
||||||
shutdown( listenfd, SD_BOTH );
|
if ( ret_code == -1 ) {
|
||||||
UpnpCloseSocket( listenfd );
|
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 );
|
miniServerStopSock = socket( AF_INET, SOCK_DGRAM, 0 );
|
||||||
if ( miniServerStopSock == -1 ) {
|
if ( miniServerStopSock == -1 ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_CRITICAL, MSERV, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_CRITICAL, MSERV, __FILE__, __LINE__,
|
||||||
"Error in socket(): %s\n", errorBuffer );
|
"Error in socket(): %s\n", errorBuffer );
|
||||||
shutdown( listenfd, SD_BOTH );
|
shutdown( listenfd4, SD_BOTH );
|
||||||
UpnpCloseSocket( listenfd );
|
UpnpCloseSocket( listenfd4 );
|
||||||
|
shutdown( listenfd6, SD_BOTH );
|
||||||
|
UpnpCloseSocket( listenfd6 );
|
||||||
|
|
||||||
return UPNP_E_OUTOF_SOCKET;
|
return UPNP_E_OUTOF_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind to local socket
|
// bind to local socket
|
||||||
memset( ( char * )&serverAddr, 0, sizeof( struct sockaddr_in ) );
|
memset( &__ss_v4, 0, sizeof( __ss_v4 ) );
|
||||||
serverAddr.sin_family = AF_INET;
|
serverAddr4->sin_family = AF_INET;
|
||||||
serverAddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );
|
serverAddr4->sin_addr.s_addr = inet_addr( "127.0.0.1" );
|
||||||
ret = bind( miniServerStopSock, (struct sockaddr *)&serverAddr,
|
ret = bind( miniServerStopSock, (struct sockaddr *)&__ss_v4,
|
||||||
sizeof (serverAddr) );
|
sizeof(__ss_v4) );
|
||||||
if ( ret == -1 ) {
|
if ( ret == -1 ) {
|
||||||
UpnpPrintf( UPNP_CRITICAL,
|
UpnpPrintf( UPNP_CRITICAL,
|
||||||
MSERV, __FILE__, __LINE__,
|
MSERV, __FILE__, __LINE__,
|
||||||
"Error in binding localhost!!!\n" );
|
"Error in binding localhost!!!\n" );
|
||||||
shutdown( listenfd, SD_BOTH );
|
shutdown( listenfd4, SD_BOTH );
|
||||||
UpnpCloseSocket( listenfd );
|
UpnpCloseSocket( listenfd4 );
|
||||||
|
shutdown( listenfd6, SD_BOTH );
|
||||||
|
UpnpCloseSocket( listenfd6 );
|
||||||
shutdown( miniServerStopSock, SD_BOTH );
|
shutdown( miniServerStopSock, SD_BOTH );
|
||||||
UpnpCloseSocket( miniServerStopSock );
|
UpnpCloseSocket( miniServerStopSock );
|
||||||
|
|
||||||
@ -682,14 +873,17 @@ get_miniserver_sockets( MiniServerSockArray * out,
|
|||||||
if ( miniStopSockPort <= 0 ) {
|
if ( miniStopSockPort <= 0 ) {
|
||||||
shutdown( miniServerStopSock, SD_BOTH );
|
shutdown( miniServerStopSock, SD_BOTH );
|
||||||
UpnpCloseSocket( miniServerStopSock );
|
UpnpCloseSocket( miniServerStopSock );
|
||||||
shutdown( listenfd, SD_BOTH );
|
shutdown( listenfd4, SD_BOTH );
|
||||||
UpnpCloseSocket( listenfd );
|
UpnpCloseSocket( listenfd4 );
|
||||||
|
shutdown( listenfd6, SD_BOTH );
|
||||||
|
UpnpCloseSocket( listenfd6 );
|
||||||
|
|
||||||
return UPNP_E_INTERNAL_ERROR;
|
return UPNP_E_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
out->stopPort = miniStopSockPort;
|
out->stopPort = miniStopSockPort;
|
||||||
out->miniServerSock = listenfd;
|
out->miniServerSock4 = listenfd4;
|
||||||
|
out->miniServerSock6 = listenfd6;
|
||||||
out->miniServerStopSock = miniServerStopSock;
|
out->miniServerStopSock = miniServerStopSock;
|
||||||
|
|
||||||
return UPNP_E_SUCCESS;
|
return UPNP_E_SUCCESS;
|
||||||
@ -698,27 +892,29 @@ get_miniserver_sockets( MiniServerSockArray * out,
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function: StartMiniServer
|
* Function: StartMiniServer
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters:
|
||||||
* unsigned short listen_port - Port on which the server listens for
|
* IN OUT unsigned short *listen_port4 ; Port on which the server
|
||||||
* incoming connections
|
* listens for incoming IPv4 connections.
|
||||||
|
* IN OUT unsigned short *listen_port6 ; Port on which the server
|
||||||
|
* listens for incoming IPv6 connections.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description: Initialize the sockets functionality for the
|
||||||
* Initialize the sockets functionality for the
|
|
||||||
* Miniserver. Initialize a thread pool job to run the MiniServer
|
* Miniserver. Initialize a thread pool job to run the MiniServer
|
||||||
* and the job to the thread pool. If listen port is 0, port is
|
* and the job to the thread pool. If listen port is 0, port is
|
||||||
* dynamically picked
|
* 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.
|
* allowed delay aborts the attempt to launch the MiniServer.
|
||||||
*
|
*
|
||||||
* Return: int
|
* Return: int;
|
||||||
* Actual port socket is bound to - On Success
|
* On success: UPNP_E_SUCCESS
|
||||||
* A negative number UPNP_E_XXX - On Error
|
* On error: PNP_E_XXX
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
int
|
int
|
||||||
StartMiniServer( unsigned short listen_port )
|
StartMiniServer( unsigned short* listen_port4,
|
||||||
|
unsigned short* listen_port6 )
|
||||||
{
|
{
|
||||||
int success;
|
int ret_code;
|
||||||
int count;
|
int count;
|
||||||
int max_count = 10000;
|
int max_count = 10000;
|
||||||
|
|
||||||
@ -733,39 +929,48 @@ StartMiniServer( unsigned short listen_port )
|
|||||||
if( miniSocket == NULL ) {
|
if( miniSocket == NULL ) {
|
||||||
return UPNP_E_OUTOF_MEMORY;
|
return UPNP_E_OUTOF_MEMORY;
|
||||||
}
|
}
|
||||||
|
memset( miniSocket, 0, sizeof(*miniSocket) );
|
||||||
|
|
||||||
success = get_miniserver_sockets( miniSocket, listen_port );
|
ret_code = get_miniserver_sockets( miniSocket, *listen_port4, *listen_port6 );
|
||||||
if( success != UPNP_E_SUCCESS ) {
|
if( ret_code != UPNP_E_SUCCESS ) {
|
||||||
free( miniSocket );
|
free( miniSocket );
|
||||||
return success;
|
return ret_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
success = get_ssdp_sockets( miniSocket );
|
ret_code = get_ssdp_sockets( miniSocket );
|
||||||
if( success != UPNP_E_SUCCESS ) {
|
if( ret_code != UPNP_E_SUCCESS ) {
|
||||||
shutdown( miniSocket->miniServerSock, SD_BOTH );
|
shutdown( miniSocket->miniServerSock4, SD_BOTH );
|
||||||
UpnpCloseSocket( miniSocket->miniServerSock );
|
UpnpCloseSocket( miniSocket->miniServerSock4 );
|
||||||
|
shutdown( miniSocket->miniServerSock6, SD_BOTH );
|
||||||
|
UpnpCloseSocket( miniSocket->miniServerSock6 );
|
||||||
shutdown( miniSocket->miniServerStopSock, SD_BOTH );
|
shutdown( miniSocket->miniServerStopSock, SD_BOTH );
|
||||||
UpnpCloseSocket( miniSocket->miniServerStopSock );
|
UpnpCloseSocket( miniSocket->miniServerStopSock );
|
||||||
free( miniSocket );
|
free( miniSocket );
|
||||||
|
|
||||||
return success;
|
return ret_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
TPJobInit( &job, (start_routine)RunMiniServer, (void *)miniSocket );
|
TPJobInit( &job, (start_routine)RunMiniServer, (void *)miniSocket );
|
||||||
TPJobSetPriority( &job, MED_PRIORITY );
|
TPJobSetPriority( &job, MED_PRIORITY );
|
||||||
TPJobSetFreeFunction( &job, ( free_routine ) free );
|
TPJobSetFreeFunction( &job, ( free_routine ) free );
|
||||||
|
|
||||||
success = ThreadPoolAddPersistent( &gMiniServerThreadPool, &job, NULL );
|
ret_code = ThreadPoolAddPersistent( &gMiniServerThreadPool, &job, NULL );
|
||||||
if ( success < 0 ) {
|
if ( ret_code < 0 ) {
|
||||||
shutdown( miniSocket->miniServerSock, SD_BOTH );
|
shutdown( miniSocket->miniServerSock4, SD_BOTH );
|
||||||
UpnpCloseSocket( miniSocket->miniServerSock );
|
UpnpCloseSocket( miniSocket->miniServerSock4 );
|
||||||
|
shutdown( miniSocket->miniServerSock6, SD_BOTH );
|
||||||
|
UpnpCloseSocket( miniSocket->miniServerSock6 );
|
||||||
shutdown( miniSocket->miniServerStopSock, SD_BOTH );
|
shutdown( miniSocket->miniServerStopSock, SD_BOTH );
|
||||||
UpnpCloseSocket( miniSocket->miniServerStopSock );
|
UpnpCloseSocket( miniSocket->miniServerStopSock );
|
||||||
shutdown( miniSocket->ssdpSock, SD_BOTH );
|
shutdown( miniSocket->ssdpSock4, SD_BOTH );
|
||||||
UpnpCloseSocket( miniSocket->ssdpSock );
|
UpnpCloseSocket( miniSocket->ssdpSock4 );
|
||||||
|
shutdown( miniSocket->ssdpSock6, SD_BOTH );
|
||||||
|
UpnpCloseSocket( miniSocket->ssdpSock6 );
|
||||||
#ifdef INCLUDE_CLIENT_APIS
|
#ifdef INCLUDE_CLIENT_APIS
|
||||||
shutdown( miniSocket->ssdpReqSock, SD_BOTH );
|
shutdown( miniSocket->ssdpReqSock4, SD_BOTH );
|
||||||
UpnpCloseSocket( miniSocket->ssdpReqSock );
|
UpnpCloseSocket( miniSocket->ssdpReqSock4 );
|
||||||
|
shutdown( miniSocket->ssdpReqSock6, SD_BOTH );
|
||||||
|
UpnpCloseSocket( miniSocket->ssdpReqSock6 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return UPNP_E_OUTOF_MEMORY;
|
return UPNP_E_OUTOF_MEMORY;
|
||||||
@ -779,21 +984,29 @@ StartMiniServer( unsigned short listen_port )
|
|||||||
|
|
||||||
// taking too long to start that thread
|
// taking too long to start that thread
|
||||||
if ( count >= max_count ) {
|
if ( count >= max_count ) {
|
||||||
shutdown( miniSocket->miniServerSock, SD_BOTH );
|
shutdown( miniSocket->miniServerSock4, SD_BOTH );
|
||||||
UpnpCloseSocket( miniSocket->miniServerSock );
|
UpnpCloseSocket( miniSocket->miniServerSock4 );
|
||||||
|
shutdown( miniSocket->miniServerSock6, SD_BOTH );
|
||||||
|
UpnpCloseSocket( miniSocket->miniServerSock6 );
|
||||||
shutdown( miniSocket->miniServerStopSock, SD_BOTH );
|
shutdown( miniSocket->miniServerStopSock, SD_BOTH );
|
||||||
UpnpCloseSocket( miniSocket->miniServerStopSock );
|
UpnpCloseSocket( miniSocket->miniServerStopSock );
|
||||||
shutdown( miniSocket->ssdpSock, SD_BOTH );
|
shutdown( miniSocket->ssdpSock4, SD_BOTH );
|
||||||
UpnpCloseSocket( miniSocket->ssdpSock );
|
UpnpCloseSocket( miniSocket->ssdpSock4 );
|
||||||
|
shutdown( miniSocket->ssdpSock6, SD_BOTH );
|
||||||
|
UpnpCloseSocket( miniSocket->ssdpSock6 );
|
||||||
#ifdef INCLUDE_CLIENT_APIS
|
#ifdef INCLUDE_CLIENT_APIS
|
||||||
shutdown( miniSocket->ssdpReqSock, SD_BOTH );
|
shutdown( miniSocket->ssdpReqSock4, SD_BOTH );
|
||||||
UpnpCloseSocket( miniSocket->ssdpReqSock );
|
UpnpCloseSocket( miniSocket->ssdpReqSock4 );
|
||||||
|
shutdown( miniSocket->ssdpReqSock6, SD_BOTH );
|
||||||
|
UpnpCloseSocket( miniSocket->ssdpReqSock6 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return UPNP_E_INTERNAL_ERROR;
|
return UPNP_E_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
*listen_port4 = miniSocket->miniServerPort4;
|
||||||
|
*listen_port6 = miniSocket->miniServerPort6;
|
||||||
|
|
||||||
return miniSocket->miniServerPort;
|
return UPNP_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -814,7 +1027,7 @@ StopMiniServer()
|
|||||||
{
|
{
|
||||||
char errorBuffer[ERROR_BUFFER_LEN];
|
char errorBuffer[ERROR_BUFFER_LEN];
|
||||||
int socklen = sizeof( struct sockaddr_in );
|
int socklen = sizeof( struct sockaddr_in );
|
||||||
int sock;
|
SOCKET sock;
|
||||||
struct sockaddr_in ssdpAddr;
|
struct sockaddr_in ssdpAddr;
|
||||||
char buf[256] = "ShutDown";
|
char buf[256] = "ShutDown";
|
||||||
int bufLen = strlen( buf );
|
int bufLen = strlen( buf );
|
||||||
|
@ -175,13 +175,13 @@ http_Connect( IN uri_type * destination_url,
|
|||||||
|
|
||||||
http_FixUrl( destination_url, url );
|
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 ) {
|
if( connfd == -1 ) {
|
||||||
return UPNP_E_OUTOF_SOCKET;
|
return UPNP_E_OUTOF_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( connect( connfd, ( struct sockaddr * )&url->hostport.IPv4address,
|
if( connect( connfd, ( struct sockaddr * )&url->hostport.IPaddress,
|
||||||
sizeof( struct sockaddr_in ) ) == -1 ) {
|
sizeof( url->hostport.IPaddress ) ) == -1 ) {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
UpnpPrintf(UPNP_CRITICAL, HTTP, __FILE__, __LINE__,
|
UpnpPrintf(UPNP_CRITICAL, HTTP, __FILE__, __LINE__,
|
||||||
"connect error: %d\n", WSAGetLastError());
|
"connect error: %d\n", WSAGetLastError());
|
||||||
@ -521,7 +521,7 @@ http_RequestAndResponse( IN uri_type * destination,
|
|||||||
int http_error_code;
|
int http_error_code;
|
||||||
SOCKINFO info;
|
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 ) {
|
if( tcp_connection == -1 ) {
|
||||||
parser_response_init( response, req_method );
|
parser_response_init( response, req_method );
|
||||||
return UPNP_E_SOCKET_ERROR;
|
return UPNP_E_SOCKET_ERROR;
|
||||||
@ -535,7 +535,7 @@ http_RequestAndResponse( IN uri_type * destination,
|
|||||||
// connect
|
// connect
|
||||||
ret_code = connect( info.socket,
|
ret_code = connect( info.socket,
|
||||||
( struct sockaddr * )&destination->hostport.
|
( struct sockaddr * )&destination->hostport.
|
||||||
IPv4address, sizeof( struct sockaddr_in ) );
|
IPaddress, sizeof( struct sockaddr_storage ) );
|
||||||
|
|
||||||
if( ret_code == -1 ) {
|
if( ret_code == -1 ) {
|
||||||
sock_destroy( &info, SD_BOTH );
|
sock_destroy( &info, SD_BOTH );
|
||||||
@ -1005,7 +1005,7 @@ http_OpenHttpPost( IN const char *url_str,
|
|||||||
|
|
||||||
handle->contentLength = contentLength;
|
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 ) {
|
if( tcp_connection == -1 ) {
|
||||||
ret_code = UPNP_E_SOCKET_ERROR;
|
ret_code = UPNP_E_SOCKET_ERROR;
|
||||||
goto errorHandler;
|
goto errorHandler;
|
||||||
@ -1019,8 +1019,8 @@ http_OpenHttpPost( IN const char *url_str,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret_code = connect( handle->sock_info.socket,
|
ret_code = connect( handle->sock_info.socket,
|
||||||
( struct sockaddr * )&url.hostport.IPv4address,
|
( struct sockaddr * )&url.hostport.IPaddress,
|
||||||
sizeof( struct sockaddr_in ) );
|
sizeof( struct sockaddr_storage ) );
|
||||||
|
|
||||||
if( ret_code == -1 ) {
|
if( ret_code == -1 ) {
|
||||||
sock_destroy( &handle->sock_info, SD_BOTH );
|
sock_destroy( &handle->sock_info, SD_BOTH );
|
||||||
@ -1587,7 +1587,7 @@ http_OpenHttpGetProxy( IN const char *url_str,
|
|||||||
handle->cancel = 0;
|
handle->cancel = 0;
|
||||||
parser_response_init( &handle->response, HTTPMETHOD_GET );
|
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 ) {
|
if( tcp_connection == -1 ) {
|
||||||
ret_code = UPNP_E_SOCKET_ERROR;
|
ret_code = UPNP_E_SOCKET_ERROR;
|
||||||
goto errorHandler;
|
goto errorHandler;
|
||||||
@ -1601,8 +1601,8 @@ http_OpenHttpGetProxy( IN const char *url_str,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret_code = connect( handle->sock_info.socket,
|
ret_code = connect( handle->sock_info.socket,
|
||||||
( struct sockaddr * )&peer->hostport.IPv4address,
|
( struct sockaddr * )&peer->hostport.IPaddress,
|
||||||
sizeof( struct sockaddr_in ) );
|
sizeof( struct sockaddr_storage ) );
|
||||||
|
|
||||||
if( ret_code == -1 ) {
|
if( ret_code == -1 ) {
|
||||||
sock_destroy( &handle->sock_info, SD_BOTH );
|
sock_destroy( &handle->sock_info, SD_BOTH );
|
||||||
@ -2236,7 +2236,7 @@ http_OpenHttpGetEx( IN const char *url_str,
|
|||||||
handle->entity_offset = 0;
|
handle->entity_offset = 0;
|
||||||
parser_response_init( &handle->response, HTTPMETHOD_GET );
|
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 ) {
|
if( tcp_connection == -1 ) {
|
||||||
errCode = UPNP_E_SOCKET_ERROR;
|
errCode = UPNP_E_SOCKET_ERROR;
|
||||||
free( handle );
|
free( handle );
|
||||||
@ -2252,8 +2252,8 @@ http_OpenHttpGetEx( IN const char *url_str,
|
|||||||
}
|
}
|
||||||
|
|
||||||
errCode = connect( handle->sock_info.socket,
|
errCode = connect( handle->sock_info.socket,
|
||||||
( struct sockaddr * )&url.hostport.IPv4address,
|
( struct sockaddr * )&url.hostport.IPaddress,
|
||||||
sizeof( struct sockaddr_in ) );
|
sizeof( struct sockaddr_storage ) );
|
||||||
if( errCode == -1 ) {
|
if( errCode == -1 ) {
|
||||||
sock_destroy( &handle->sock_info, SD_BOTH );
|
sock_destroy( &handle->sock_info, SD_BOTH );
|
||||||
errCode = UPNP_E_SOCKET_CONNECT;
|
errCode = UPNP_E_SOCKET_CONNECT;
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* OUT SOCKINFO* info ; Socket Information Object
|
* 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
|
* Description : Assign the passed in socket descriptor to socket
|
||||||
* descriptor in the SOCKINFO structure.
|
* descriptor in the SOCKINFO structure.
|
||||||
@ -76,7 +76,7 @@
|
|||||||
************************************************************************/
|
************************************************************************/
|
||||||
int
|
int
|
||||||
sock_init( OUT SOCKINFO * info,
|
sock_init( OUT SOCKINFO * info,
|
||||||
IN int sockfd )
|
IN SOCKET sockfd )
|
||||||
{
|
{
|
||||||
assert( info );
|
assert( info );
|
||||||
|
|
||||||
@ -91,10 +91,9 @@ sock_init( OUT SOCKINFO * info,
|
|||||||
* Function : sock_init_with_ip
|
* Function : sock_init_with_ip
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* OUT SOCKINFO* info ; Socket Information Object
|
* OUT SOCKINFO* info ; Socket Information Object
|
||||||
* IN int sockfd ; Socket Descriptor
|
* IN SOCKET sockfd ; Socket Descriptor
|
||||||
* IN struct in_addr foreign_ip_addr ; Remote IP Address
|
* IN struct sockaddr* foreign_sockaddr; remote socket address.
|
||||||
* IN unsigned short foreign_ip_port ; Remote Port number
|
|
||||||
*
|
*
|
||||||
* Description : Calls the sock_init function and assigns the passed in
|
* Description : Calls the sock_init function and assigns the passed in
|
||||||
* IP address and port to the IP address and port in the SOCKINFO
|
* IP address and port to the IP address and port in the SOCKINFO
|
||||||
@ -109,9 +108,8 @@ sock_init( OUT SOCKINFO * info,
|
|||||||
************************************************************************/
|
************************************************************************/
|
||||||
int
|
int
|
||||||
sock_init_with_ip( OUT SOCKINFO * info,
|
sock_init_with_ip( OUT SOCKINFO * info,
|
||||||
IN int sockfd,
|
IN SOCKET sockfd,
|
||||||
IN struct in_addr foreign_ip_addr,
|
IN struct sockaddr* foreign_sockaddr )
|
||||||
IN unsigned short foreign_ip_port )
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -120,8 +118,8 @@ sock_init_with_ip( OUT SOCKINFO * info,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->foreign_ip_addr = foreign_ip_addr;
|
memcpy( &info->foreign_sockaddr, foreign_sockaddr,
|
||||||
info->foreign_ip_port = foreign_ip_port;
|
sizeof( info->foreign_sockaddr) );
|
||||||
|
|
||||||
return UPNP_E_SUCCESS;
|
return UPNP_E_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -149,9 +147,11 @@ int
|
|||||||
sock_destroy( INOUT SOCKINFO * info,
|
sock_destroy( INOUT SOCKINFO * info,
|
||||||
int ShutdownMethod )
|
int ShutdownMethod )
|
||||||
{
|
{
|
||||||
shutdown( info->socket, ShutdownMethod );
|
if( info->socket != INVALID_SOCKET ) {
|
||||||
if( UpnpCloseSocket( info->socket ) == -1 ) {
|
shutdown( info->socket, ShutdownMethod );
|
||||||
return UPNP_E_SOCKET_ERROR;
|
if( UpnpCloseSocket( info->socket ) == -1 ) {
|
||||||
|
return UPNP_E_SOCKET_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return UPNP_E_SUCCESS;
|
return UPNP_E_SUCCESS;
|
||||||
@ -190,7 +190,7 @@ sock_read_write( IN SOCKINFO * info,
|
|||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
int numBytes;
|
int numBytes;
|
||||||
time_t start_time = time( NULL );
|
time_t start_time = time( NULL );
|
||||||
int sockfd = info->socket;
|
SOCKET sockfd = info->socket;
|
||||||
long bytes_sent = 0,
|
long bytes_sent = 0,
|
||||||
byte_left = 0,
|
byte_left = 0,
|
||||||
num_written;
|
num_written;
|
||||||
@ -202,9 +202,9 @@ sock_read_write( IN SOCKINFO * info,
|
|||||||
FD_ZERO( &readSet );
|
FD_ZERO( &readSet );
|
||||||
FD_ZERO( &writeSet );
|
FD_ZERO( &writeSet );
|
||||||
if( bRead ) {
|
if( bRead ) {
|
||||||
FD_SET( ( unsigned )sockfd, &readSet );
|
FD_SET( sockfd, &readSet );
|
||||||
} else {
|
} else {
|
||||||
FD_SET( ( unsigned )sockfd, &writeSet );
|
FD_SET( sockfd, &writeSet );
|
||||||
}
|
}
|
||||||
|
|
||||||
timeout.tv_sec = *timeoutSecs;
|
timeout.tv_sec = *timeoutSecs;
|
||||||
|
@ -41,10 +41,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "uri.h"
|
#include "uri.h"
|
||||||
|
#include "upnpapi.h"
|
||||||
#ifdef WIN32
|
|
||||||
#include "inet_pton.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -224,28 +221,6 @@ parse_uric( const char *in,
|
|||||||
return i;
|
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
|
* Function : copy_token
|
||||||
@ -328,8 +303,9 @@ copy_URL_list( URL_list * in,
|
|||||||
in->URLs, &out->parsedURLs[i].hostport.text,
|
in->URLs, &out->parsedURLs[i].hostport.text,
|
||||||
out->URLs );
|
out->URLs );
|
||||||
|
|
||||||
copy_sockaddr_in( &in->parsedURLs[i].hostport.IPv4address,
|
memcpy( &out->parsedURLs[i].hostport.IPaddress,
|
||||||
&out->parsedURLs[i].hostport.IPv4address );
|
&in->parsedURLs[i].hostport.IPaddress,
|
||||||
|
sizeof(struct sockaddr_storage) );
|
||||||
}
|
}
|
||||||
out->size = in->size;
|
out->size = in->size;
|
||||||
return HTTP_SUCCESS;
|
return HTTP_SUCCESS;
|
||||||
@ -490,48 +466,13 @@ token_cmp( token * in1,
|
|||||||
return memcmp( in1->buff, in2->buff, in1->size );
|
return memcmp( in1->buff, in2->buff, in1->size );
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
|
||||||
* Function : parse_port
|
|
||||||
*
|
|
||||||
* Parameters :
|
|
||||||
* int max ; sets a maximum limit
|
|
||||||
* char * port ; port to be parsed.
|
|
||||||
* unsigned short * out ; out parameter where the port is parsed
|
|
||||||
* and converted into network format
|
|
||||||
*
|
|
||||||
* Description : parses a port (i.e. '4000') and converts it into a
|
|
||||||
* network ordered unsigned short int.
|
|
||||||
*
|
|
||||||
* Return : int ;
|
|
||||||
*
|
|
||||||
* Note :
|
|
||||||
************************************************************************/
|
|
||||||
int
|
|
||||||
parse_port( int max,
|
|
||||||
const char *port,
|
|
||||||
unsigned short *out )
|
|
||||||
{
|
|
||||||
|
|
||||||
const char *finger = port;
|
|
||||||
const char *max_ptr = finger + max;
|
|
||||||
unsigned short temp = 0;
|
|
||||||
|
|
||||||
while( ( finger < max_ptr ) && ( isdigit( *finger ) ) ) {
|
|
||||||
temp = temp * 10;
|
|
||||||
temp += ( *finger ) - '0';
|
|
||||||
finger++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*out = htons( temp );
|
|
||||||
return finger - port;
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : parse_hostport
|
* Function : parse_hostport
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* char *in ; string of characters representing host and port
|
* 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
|
* hostport_type *out ; out parameter where the host and port
|
||||||
* are represented as an internet address
|
* are represented as an internet address
|
||||||
*
|
*
|
||||||
@ -540,7 +481,8 @@ parse_port( int max,
|
|||||||
* hostport_type struct with internet address and a token
|
* hostport_type struct with internet address and a token
|
||||||
* representing the full host and port. uses gethostbyname.
|
* 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 :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
@ -549,165 +491,145 @@ parse_hostport( const char *in,
|
|||||||
int max,
|
int max,
|
||||||
hostport_type * out )
|
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;
|
memset( out, 0, sizeof(hostport_type) );
|
||||||
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;
|
|
||||||
|
|
||||||
out->text.size = 0;
|
// Work on a copy of the input string.
|
||||||
out->text.buff = NULL;
|
strncpy( workbuf, in, sizeof(workbuf) );
|
||||||
|
|
||||||
out->IPv4address.sin_port = htons( 80 ); //default port is 80
|
c = workbuf;
|
||||||
memset( &out->IPv4address.sin_zero, 0, 8 );
|
if( *c == '[' ) {
|
||||||
|
// IPv6 addresses are enclosed in square brackets.
|
||||||
while( ( i < max ) && ( in[i] != ':' ) && ( in[i] != '/' )
|
srvname = ++c;
|
||||||
&& ( ( isalnum( in[i] ) ) || ( in[i] == '.' )
|
while( *c != '\0' && *c != ']' ) {
|
||||||
|| ( in[i] == '-' ) ) ) {
|
c++;
|
||||||
i++;
|
|
||||||
if( in[i] == '.' ) {
|
|
||||||
last_dot = i;
|
|
||||||
}
|
}
|
||||||
|
if( *c == '\0' ) {
|
||||||
|
// did not find closing bracket.
|
||||||
|
return UPNP_E_INVALID_URL;
|
||||||
|
}
|
||||||
|
// NULL terminate the srvname and then increment c.
|
||||||
|
*c++ = '\0'; // overwrite the ']'
|
||||||
|
if( *c == ':' ) {
|
||||||
|
has_port = 1;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
af = AF_INET6;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
host_size = i;
|
// IPv4 address -OR- host name.
|
||||||
|
srvname = c;
|
||||||
if( ( i < max ) && ( in[i] == ':' ) ) {
|
while( (*c != ':') && (*c != '/') && ( (isalnum(*c)) || (*c == '.') || (*c == '-') ) ) {
|
||||||
begin_port = i + 1;
|
if( *c == '.' )
|
||||||
//convert port
|
last_dot = c;
|
||||||
if( !( hostport_size = parse_port( max - begin_port,
|
c++;
|
||||||
&in[begin_port],
|
|
||||||
&out->IPv4address.sin_port ) ) )
|
|
||||||
{
|
|
||||||
return UPNP_E_INVALID_URL;
|
|
||||||
}
|
}
|
||||||
hostport_size += begin_port;
|
has_port = (*c == ':') ? 1 : 0;
|
||||||
} else
|
// NULL terminate the srvname
|
||||||
hostport_size = host_size;
|
*c = '\0';
|
||||||
|
if( has_port == 1 )
|
||||||
|
c++;
|
||||||
|
|
||||||
//convert to temporary null terminated string
|
if( last_dot != NULL && isdigit(*(last_dot+1)) ) {
|
||||||
temp_host_name = ( char * )malloc( host_size + 1 );
|
// Must be an IPv4 address.
|
||||||
|
af = AF_INET;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
} else {
|
else {
|
||||||
int errCode = 0;
|
// Must be a host name.
|
||||||
|
struct addrinfo hints, *res, *res0;
|
||||||
|
|
||||||
//call gethostbyname_r (reentrant form of gethostbyname)
|
memset(&hints, 0, sizeof(hints));
|
||||||
// TODO: Use autoconf to discover this rather than the
|
hints.ai_family = AF_UNSPEC;
|
||||||
// platform-specific stuff below
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
#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;
|
|
||||||
}
|
|
||||||
#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;
|
|
||||||
|
|
||||||
h = NULL;
|
ret = getaddrinfo(srvname, NULL, &hints, &res0);
|
||||||
memset(&hints, 0, sizeof(hints));
|
if( ret == 0 ) {
|
||||||
hints.ai_family = PF_INET;
|
for (res = res0; res; res = res->ai_next) {
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
if( res->ai_family == AF_INET ||
|
||||||
errCode = getaddrinfo(temp_host_name, "http", &hints, &res0);
|
res->ai_family == AF_INET6 ) {
|
||||||
|
// Found a valid IPv4 or IPv6 address.
|
||||||
if (!errCode) {
|
memcpy( &out->IPaddress, res->ai_addr,
|
||||||
for (res = res0; res; res = res->ai_next) {
|
res->ai_addrlen );
|
||||||
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;
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
freeaddrinfo(res0);
|
||||||
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;
|
|
||||||
|
|
||||||
|
if( res == NULL ) {
|
||||||
|
// Didn't find an AF_INET or AF_INET6 address.
|
||||||
|
return UPNP_E_INVALID_URL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
else {
|
||||||
out->IPv4address.sin_addr.s_addr = 0;
|
// getaddrinfo failed.
|
||||||
out->IPv4address.sin_family = AF_INET;
|
return UPNP_E_INVALID_URL;
|
||||||
free( temp_host_name );
|
}
|
||||||
temp_host_name = NULL;
|
|
||||||
return UPNP_E_INVALID_URL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( temp_host_name ) {
|
// Check if a port is specified.
|
||||||
free( temp_host_name );
|
if( has_port == 1 ) {
|
||||||
temp_host_name = NULL;
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.size = hostport_size;
|
||||||
out->text.buff = in;
|
out->text.buff = in;
|
||||||
return hostport_size;
|
return hostport_size;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -1069,10 +991,7 @@ parse_uri( const char *in,
|
|||||||
return begin_path;
|
return begin_path;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
out->hostport.IPv4address.sin_port = 0;
|
memset( &out->hostport, 0, sizeof(out->hostport) );
|
||||||
out->hostport.IPv4address.sin_addr.s_addr = 0;
|
|
||||||
out->hostport.text.size = 0;
|
|
||||||
out->hostport.text.buff = 0;
|
|
||||||
begin_path = begin_hostport;
|
begin_path = begin_hostport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ typedef struct TOKEN {
|
|||||||
//the full string representation
|
//the full string representation
|
||||||
typedef struct HOSTPORT {
|
typedef struct HOSTPORT {
|
||||||
token text; //full host port
|
token text; //full host port
|
||||||
struct sockaddr_in IPv4address; //Network Byte Order
|
struct sockaddr_storage IPaddress; //Network Byte Order
|
||||||
} hostport_type;
|
} hostport_type;
|
||||||
|
|
||||||
//Represents a URI
|
//Represents a URI
|
||||||
|
@ -42,17 +42,21 @@ extern SOCKET gMiniServerStopSock;
|
|||||||
|
|
||||||
typedef struct MServerSockArray {
|
typedef struct MServerSockArray {
|
||||||
/* socket for listening for miniserver requests */
|
/* socket for listening for miniserver requests */
|
||||||
int miniServerSock;
|
SOCKET miniServerSock4;
|
||||||
|
SOCKET miniServerSock6;
|
||||||
/* socket for stopping miniserver */
|
/* socket for stopping miniserver */
|
||||||
int miniServerStopSock;
|
SOCKET miniServerStopSock;
|
||||||
/* socket for incoming advertisments and search requests */
|
/* socket for incoming advertisments and search requests */
|
||||||
int ssdpSock;
|
SOCKET ssdpSock4;
|
||||||
|
SOCKET ssdpSock6;
|
||||||
|
|
||||||
int stopPort;
|
SOCKET stopPort;
|
||||||
int miniServerPort;
|
SOCKET miniServerPort4;
|
||||||
|
SOCKET miniServerPort6;
|
||||||
|
|
||||||
/* socket for sending search requests and receiving search replies */
|
/* socket for sending search requests and receiving search replies */
|
||||||
CLIENTONLY(int ssdpReqSock;)
|
CLIENTONLY(SOCKET ssdpReqSock4;)
|
||||||
|
CLIENTONLY(SOCKET ssdpReqSock6;)
|
||||||
} MiniServerSockArray;
|
} MiniServerSockArray;
|
||||||
|
|
||||||
|
|
||||||
@ -110,8 +114,10 @@ void SetGenaCallback( MiniServerCallback callback );
|
|||||||
* Function: StartMiniServer
|
* Function: StartMiniServer
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* unsigned short listen_port ; Port on which the server listens for
|
* IN OUT unsigned short *listen_port4 ; Port on which the server
|
||||||
* incoming connections
|
* 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
|
* Miniserver. Initialize a thread pool job to run the MiniServer
|
||||||
@ -122,10 +128,11 @@ void SetGenaCallback( MiniServerCallback callback );
|
|||||||
* allowed delay aborts the attempt to launch the MiniServer.
|
* allowed delay aborts the attempt to launch the MiniServer.
|
||||||
*
|
*
|
||||||
* Return: int;
|
* Return: int;
|
||||||
* Actual port socket is bound to - On Success:
|
* On success: UPNP_E_SUCCESS
|
||||||
* A negative number UPNP_E_XXX - On Error
|
* On error: UPNP_E_XXX
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
int StartMiniServer( unsigned short listen_port );
|
int StartMiniServer( IN OUT unsigned short* listen_port4,
|
||||||
|
IN OUT unsigned short* listen_port6 );
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function: StopMiniServer
|
* Function: StopMiniServer
|
||||||
|
@ -48,11 +48,10 @@
|
|||||||
|
|
||||||
typedef struct
|
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;
|
// the following two fields are filled only in incoming requests;
|
||||||
struct in_addr foreign_ip_addr;
|
struct sockaddr_storage foreign_sockaddr;
|
||||||
unsigned short foreign_ip_port;
|
|
||||||
|
|
||||||
} SOCKINFO;
|
} SOCKINFO;
|
||||||
|
|
||||||
@ -65,7 +64,7 @@ typedef struct
|
|||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* OUT SOCKINFO* info ; Socket Information Object
|
* 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
|
* Description : Assign the passed in socket descriptor to socket
|
||||||
* descriptor in the SOCKINFO structure.
|
* descriptor in the SOCKINFO structure.
|
||||||
@ -76,16 +75,15 @@ typedef struct
|
|||||||
* UPNP_E_SOCKET_ERROR
|
* UPNP_E_SOCKET_ERROR
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
int sock_init( OUT SOCKINFO* info, IN int sockfd );
|
int sock_init(OUT SOCKINFO* info, IN SOCKET sockfd);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : sock_init_with_ip
|
* Function : sock_init_with_ip
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* OUT SOCKINFO* info ; Socket Information Object
|
* OUT SOCKINFO* info ; Socket Information Object
|
||||||
* IN int sockfd ; Socket Descriptor
|
* IN SOCKET sockfd ; Socket Descriptor
|
||||||
* IN struct in_addr foreign_ip_addr ; Remote IP Address
|
* IN struct sockaddr* foreign_sockaddr; Remote socket address
|
||||||
* IN unsigned short foreign_ip_port ; Remote Port number
|
|
||||||
*
|
*
|
||||||
* Description : Calls the sock_init function and assigns the passed in
|
* Description : Calls the sock_init function and assigns the passed in
|
||||||
* IP address and port to the IP address and port in the SOCKINFO
|
* IP address and port to the IP address and port in the SOCKINFO
|
||||||
@ -98,8 +96,10 @@ int sock_init( OUT SOCKINFO* info, IN int sockfd );
|
|||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
int sock_init_with_ip( OUT SOCKINFO* info, IN int sockfd,
|
int sock_init_with_ip(
|
||||||
IN struct in_addr foreign_ip_addr, IN unsigned short foreign_ip_port );
|
OUT SOCKINFO* info,
|
||||||
|
IN SOCKET sockfd,
|
||||||
|
IN struct sockaddr *foreign_sockaddr);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : sock_read
|
* Function : sock_read
|
||||||
@ -162,7 +162,7 @@ int sock_write( IN SOCKINFO *info, IN char* buffer, IN size_t bufsize,
|
|||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
int sock_destroy( INOUT SOCKINFO* info,int );
|
int sock_destroy(INOUT SOCKINFO* info, int);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // #extern "C"
|
} // #extern "C"
|
||||||
|
@ -78,6 +78,7 @@ typedef enum SsdpCmdType{SSDP_ERROR=-1,
|
|||||||
//Constant
|
//Constant
|
||||||
#define BUFSIZE 2500
|
#define BUFSIZE 2500
|
||||||
#define SSDP_IP "239.255.255.250"
|
#define SSDP_IP "239.255.255.250"
|
||||||
|
#define SSDP_IPV6_LINKLOCAL "FF02::C"
|
||||||
#define SSDP_PORT 1900
|
#define SSDP_PORT 1900
|
||||||
#define NUM_TRY 3
|
#define NUM_TRY 3
|
||||||
#define NUM_COPY 1
|
#define NUM_COPY 1
|
||||||
@ -121,7 +122,7 @@ typedef struct SsdpEventStruct
|
|||||||
char Os[LINE_SIZE];
|
char Os[LINE_SIZE];
|
||||||
char Ext[LINE_SIZE];
|
char Ext[LINE_SIZE];
|
||||||
char Date[LINE_SIZE];
|
char Date[LINE_SIZE];
|
||||||
struct sockaddr_in * DestAddr;
|
struct sockaddr *DestAddr;
|
||||||
void * Cookie;
|
void * Cookie;
|
||||||
} Event;
|
} Event;
|
||||||
|
|
||||||
@ -134,7 +135,7 @@ typedef struct TData
|
|||||||
int Mx;
|
int Mx;
|
||||||
void * Cookie;
|
void * Cookie;
|
||||||
char * Data;
|
char * Data;
|
||||||
struct sockaddr_in DestAddr;
|
struct sockaddr_storage DestAddr;
|
||||||
|
|
||||||
}ThreadData;
|
}ThreadData;
|
||||||
|
|
||||||
@ -142,7 +143,7 @@ typedef struct ssdpsearchreply
|
|||||||
{
|
{
|
||||||
int MaxAge;
|
int MaxAge;
|
||||||
UpnpDevice_Handle handle;
|
UpnpDevice_Handle handle;
|
||||||
struct sockaddr_in dest_addr;
|
struct sockaddr_storage dest_addr;
|
||||||
SsdpEvent event;
|
SsdpEvent event;
|
||||||
|
|
||||||
}SsdpSearchReply;
|
}SsdpSearchReply;
|
||||||
@ -159,13 +160,14 @@ typedef struct ssdpsearcharg
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
http_parser_t parser;
|
http_parser_t parser;
|
||||||
struct sockaddr_in dest_addr;
|
struct sockaddr_storage dest_addr;
|
||||||
} ssdp_thread_data;
|
} ssdp_thread_data;
|
||||||
|
|
||||||
|
|
||||||
/* globals */
|
/* globals */
|
||||||
|
|
||||||
CLIENTONLY(extern SOCKET gSsdpReqSocket;);
|
CLIENTONLY(extern SOCKET gSsdpReqSocket4;);
|
||||||
|
CLIENTONLY(extern SOCKET gSsdpReqSocket6;);
|
||||||
|
|
||||||
typedef int (*ParserFun)(char *, Event *);
|
typedef int (*ParserFun)(char *, Event *);
|
||||||
|
|
||||||
@ -205,11 +207,11 @@ int Make_Socket_NoBlocking (int sock);
|
|||||||
#ifdef INCLUDE_DEVICE_APIS
|
#ifdef INCLUDE_DEVICE_APIS
|
||||||
void ssdp_handle_device_request(
|
void ssdp_handle_device_request(
|
||||||
IN http_message_t* hmsg,
|
IN http_message_t* hmsg,
|
||||||
IN struct sockaddr_in* dest_addr );
|
IN struct sockaddr* dest_addr );
|
||||||
#else
|
#else
|
||||||
static inline void ssdp_handle_device_request(
|
static inline void ssdp_handle_device_request(
|
||||||
IN http_message_t* hmsg,
|
IN http_message_t* hmsg,
|
||||||
IN struct sockaddr_in* dest_addr ) {}
|
IN struct sockaddr* dest_addr ) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -217,7 +219,7 @@ static inline void ssdp_handle_device_request(
|
|||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN http_message_t* hmsg: SSDP message from the device
|
* 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
|
* IN xboolean timeout: timeout kept by the control point while sending
|
||||||
* search message
|
* search message
|
||||||
* IN void* cookie: Cookie stored by the control point application.
|
* IN void* cookie: Cookie stored by the control point application.
|
||||||
@ -234,7 +236,7 @@ static inline void ssdp_handle_device_request(
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
void ssdp_handle_ctrlpt_msg(
|
void ssdp_handle_ctrlpt_msg(
|
||||||
IN http_message_t* hmsg,
|
IN http_message_t* hmsg,
|
||||||
IN struct sockaddr_in* dest_addr,
|
IN struct sockaddr* dest_addr,
|
||||||
IN xboolean timeout,
|
IN xboolean timeout,
|
||||||
IN void* cookie );
|
IN void* cookie );
|
||||||
|
|
||||||
@ -347,6 +349,7 @@ int SearchByTarget(IN int Mx, IN char *St, IN void *Cookie);
|
|||||||
* IN char *Udn :
|
* IN char *Udn :
|
||||||
* IN char *Location: Location URL.
|
* IN char *Location: Location URL.
|
||||||
* IN int Duration : Service duration in sec.
|
* IN int Duration : Service duration in sec.
|
||||||
|
* IN int AddressFamily: Device address family.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates the device advertisement request based on
|
* This function creates the device advertisement request based on
|
||||||
@ -360,7 +363,8 @@ int DeviceAdvertisement(
|
|||||||
IN int RootDev,
|
IN int RootDev,
|
||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration);
|
IN int Duration,
|
||||||
|
IN int AddressFamily);
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -373,6 +377,7 @@ int DeviceAdvertisement(
|
|||||||
* IN char *_Server:
|
* IN char *_Server:
|
||||||
* IN char *Location: Location URL
|
* IN char *Location: Location URL
|
||||||
* IN int Duration :Device duration in sec.
|
* IN int Duration :Device duration in sec.
|
||||||
|
* IN int AddressFamily: Device address family.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates a HTTP device shutdown request packet
|
* This function creates a HTTP device shutdown request packet
|
||||||
@ -387,13 +392,14 @@ int DeviceShutdown(
|
|||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *_Server,
|
IN char *_Server,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration);
|
IN int Duration,
|
||||||
|
IN int AddressFamily);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : DeviceReply
|
* Function : DeviceReply
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN struct sockaddr_in * DestAddr:destination IP address.
|
* IN struct sockaddr *DestAddr: destination IP address.
|
||||||
* IN char *DevType: Device type
|
* IN char *DevType: Device type
|
||||||
* IN int RootDev: 1 means root device 0 means embedded device.
|
* IN int RootDev: 1 means root device 0 means embedded device.
|
||||||
* IN char *Udn: Device UDN
|
* IN char *Udn: Device UDN
|
||||||
@ -408,17 +414,18 @@ int DeviceShutdown(
|
|||||||
* UPNP_E_SUCCESS if successful else appropriate error
|
* UPNP_E_SUCCESS if successful else appropriate error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int DeviceReply(
|
int DeviceReply(
|
||||||
IN struct sockaddr_in * DestAddr,
|
IN struct sockaddr *DestAddr,
|
||||||
IN char *DevType,
|
IN char *DevType,
|
||||||
IN int RootDev,
|
IN int RootDev,
|
||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *Location, IN int Duration);
|
IN char *Location,
|
||||||
|
IN int Duration);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : SendReply
|
* Function : SendReply
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN struct sockaddr_in * DestAddr:destination IP address.
|
* IN struct sockaddr *DestAddr: destination IP address.
|
||||||
* IN char *DevType: Device type
|
* IN char *DevType: Device type
|
||||||
* IN int RootDev: 1 means root device 0 means embedded device.
|
* IN int RootDev: 1 means root device 0 means embedded device.
|
||||||
* IN char * Udn: Device UDN
|
* IN char * Udn: Device UDN
|
||||||
@ -435,7 +442,7 @@ int DeviceReply(
|
|||||||
* UPNP_E_SUCCESS if successful else appropriate error
|
* UPNP_E_SUCCESS if successful else appropriate error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int SendReply(
|
int SendReply(
|
||||||
IN struct sockaddr_in * DestAddr,
|
IN struct sockaddr *DestAddr,
|
||||||
IN char *DevType,
|
IN char *DevType,
|
||||||
IN int RootDev,
|
IN int RootDev,
|
||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
@ -450,7 +457,8 @@ int SendReply(
|
|||||||
* IN char * Udn: Device UDN
|
* IN char * Udn: Device UDN
|
||||||
* IN char *ServType: Service Type.
|
* IN char *ServType: Service Type.
|
||||||
* IN char * Location: Location of Device description document.
|
* IN char * Location: Location of Device description document.
|
||||||
* IN int Duration :Life time of this device.
|
* IN int Duration: Life time of this device.
|
||||||
|
* IN int AddressFamily: Device address family
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates the advertisement packet based
|
* This function creates the advertisement packet based
|
||||||
@ -463,13 +471,14 @@ int ServiceAdvertisement(
|
|||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *ServType,
|
IN char *ServType,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration);
|
IN int Duration,
|
||||||
|
IN int AddressFamily);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : ServiceReply
|
* Function : ServiceReply
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN struct sockaddr_in *DestAddr:
|
* IN struct sockaddr *DestAddr:
|
||||||
* IN char *Udn: Device UDN
|
* IN char *Udn: Device UDN
|
||||||
* IN char *ServType: Service Type.
|
* IN char *ServType: Service Type.
|
||||||
* IN char *Server: Not used
|
* IN char *Server: Not used
|
||||||
@ -484,7 +493,7 @@ int ServiceAdvertisement(
|
|||||||
* UPNP_E_SUCCESS if successful else appropriate error
|
* UPNP_E_SUCCESS if successful else appropriate error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int ServiceReply(
|
int ServiceReply(
|
||||||
IN struct sockaddr_in *DestAddr,
|
IN struct sockaddr *DestAddr,
|
||||||
IN char *ServType,
|
IN char *ServType,
|
||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
@ -498,6 +507,7 @@ int ServiceReply(
|
|||||||
* IN char *ServType: Service Type.
|
* IN char *ServType: Service Type.
|
||||||
* IN char *Location: Location of Device description document.
|
* IN char *Location: Location of Device description document.
|
||||||
* IN int Duration :Service duration in sec.
|
* IN int Duration :Service duration in sec.
|
||||||
|
* IN int AddressFamily: Device address family
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates a HTTP service shutdown request packet
|
* This function creates a HTTP service shutdown request packet
|
||||||
@ -510,7 +520,8 @@ int ServiceShutdown(
|
|||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *ServType,
|
IN char *ServType,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration);
|
IN int Duration,
|
||||||
|
IN int AddressFamily);
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -537,7 +548,7 @@ void *advertiseAndReplyThread(IN void * data);
|
|||||||
* 1 = Send Advertisement
|
* 1 = Send Advertisement
|
||||||
* IN UpnpDevice_Handle Hnd: Device handle
|
* IN UpnpDevice_Handle Hnd: Device handle
|
||||||
* IN enum SsdpSearchType SearchType:Search type for sending replies
|
* 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 *DeviceType:Device type
|
||||||
* IN char *DeviceUDN:Device UDN
|
* IN char *DeviceUDN:Device UDN
|
||||||
* IN char *ServiceType:Service type
|
* IN char *ServiceType:Service type
|
||||||
@ -553,10 +564,9 @@ int AdvertiseAndReply(
|
|||||||
IN int AdFlag,
|
IN int AdFlag,
|
||||||
IN UpnpDevice_Handle Hnd,
|
IN UpnpDevice_Handle Hnd,
|
||||||
IN enum SsdpSearchType SearchType,
|
IN enum SsdpSearchType SearchType,
|
||||||
IN struct sockaddr_in *DestAddr,
|
IN struct sockaddr *DestAddr,
|
||||||
IN char *DeviceType,
|
IN char *DeviceType,
|
||||||
IN char *DeviceUDN,
|
IN char *DeviceUDN,
|
||||||
IN char *ServiceType, int Exp);
|
IN char *ServiceType, int Exp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -84,11 +84,12 @@ struct Handle_Info
|
|||||||
//URL information
|
//URL information
|
||||||
int MaxSubscriptions;
|
int MaxSubscriptions;
|
||||||
int MaxSubscriptionTimeOut;
|
int MaxSubscriptionTimeOut;
|
||||||
|
int DeviceAf; // Address family: AF_INET or AF_INET6
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Client only
|
// Client only
|
||||||
#ifdef INCLUDE_CLIENT_APIS
|
#ifdef INCLUDE_CLIENT_APIS
|
||||||
ClientSubscription *ClientSubList; //client subscription list
|
ClientSubscription *ClientSubList; // client subscription list
|
||||||
LinkedList SsdpSearchList; // active ssdp searches
|
LinkedList SsdpSearchList; // active ssdp searches
|
||||||
#endif
|
#endif
|
||||||
int aliasInstalled; // 0 = not installed; otherwise installed
|
int aliasInstalled; // 0 = not installed; otherwise installed
|
||||||
@ -116,13 +117,20 @@ Upnp_Handle_Type GetHandleInfo(int Hnd, struct Handle_Info **HndInfo);
|
|||||||
|
|
||||||
Upnp_Handle_Type GetClientHandleInfo(int *client_handle_out,
|
Upnp_Handle_Type GetClientHandleInfo(int *client_handle_out,
|
||||||
struct Handle_Info **HndInfo);
|
struct Handle_Info **HndInfo);
|
||||||
Upnp_Handle_Type GetDeviceHandleInfo(int *device_handle_out,
|
Upnp_Handle_Type GetDeviceHandleInfo( const int AddressFamily,
|
||||||
struct Handle_Info **HndInfo);
|
int *device_handle_out,
|
||||||
|
struct Handle_Info **HndInfo);
|
||||||
|
|
||||||
|
|
||||||
extern char LOCAL_HOST[LINE_SIZE];
|
extern char gIF_NAME[LINE_SIZE];
|
||||||
|
extern char gIF_IPV4[22]; // INET_ADDRSTRLEN
|
||||||
|
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 TimerThread gTimerThread;
|
||||||
extern ThreadPool gRecvThreadPool;
|
extern ThreadPool gRecvThreadPool;
|
||||||
@ -170,6 +178,14 @@ typedef enum { WEB_SERVER_DISABLED, WEB_SERVER_ENABLED } WebServerState;
|
|||||||
|
|
||||||
#define E_HTTP_SYNTAX -6
|
#define E_HTTP_SYNTAX -6
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
int WinsockInit();
|
||||||
|
#endif
|
||||||
|
int UpnpInitPreamble();
|
||||||
|
int UpnpInitMutexes();
|
||||||
|
int UpnpInitThreadPools();
|
||||||
|
int UpnpInitStartServers(unsigned short DestPort);
|
||||||
|
int UpnpGetIfInfo(const char *IfName);
|
||||||
void InitHandleList();
|
void InitHandleList();
|
||||||
int GetFreeHandle();
|
int GetFreeHandle();
|
||||||
int FreeHandle(int Handle);
|
int FreeHandle(int Handle);
|
||||||
@ -177,7 +193,7 @@ void UpnpThreadDistribution(struct UpnpNonblockParam * Param);
|
|||||||
|
|
||||||
|
|
||||||
void AutoAdvertise(void *input);
|
void AutoAdvertise(void *input);
|
||||||
int getlocalhostname(char *out);
|
int getlocalhostname(char *out, const int out_len);
|
||||||
|
|
||||||
extern WebServerState bWebServerState;
|
extern WebServerState bWebServerState;
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ typedef struct TOKEN {
|
|||||||
* text is a token pointing to the full string representation */
|
* text is a token pointing to the full string representation */
|
||||||
typedef struct HOSTPORT {
|
typedef struct HOSTPORT {
|
||||||
token text; //full host port
|
token text; //full host port
|
||||||
struct sockaddr_in IPv4address; //Network Byte Order
|
struct sockaddr_storage IPaddress; //Network Byte Order
|
||||||
} hostport_type;
|
} hostport_type;
|
||||||
|
|
||||||
/* Represents a URI used in parse_uri and elsewhere */
|
/* Represents a URI used in parse_uri and elsewhere */
|
||||||
|
@ -50,13 +50,13 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* INOUT IXML_Document *doc ; IXML Description document
|
* 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
|
* providing the IP address and port information
|
||||||
* IN const char* alias ; string containing the alias
|
* IN const char* alias ; string containing the alias
|
||||||
* IN time_t last_modified ; time when the XML document was
|
* IN time_t last_modified ; time when the XML document was
|
||||||
* downloaded
|
* downloaded
|
||||||
* OUT char docURL[LINE_SIZE] ; buffer to hold the URL of the
|
* OUT char docURL[LINE_SIZE] ; buffer to hold the URL of the
|
||||||
* document.
|
* document.
|
||||||
*
|
*
|
||||||
* Description : Configure the full URL for the description document.
|
* Description : Configure the full URL for the description document.
|
||||||
* Create the URL document and add alias, description information.
|
* Create the URL document and add alias, description information.
|
||||||
@ -70,10 +70,10 @@ extern "C" {
|
|||||||
* Note :
|
* Note :
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
int configure_urlbase( INOUT IXML_Document *doc,
|
int configure_urlbase( INOUT IXML_Document *doc,
|
||||||
IN const struct sockaddr_in* serverAddr,
|
IN const struct sockaddr* serverAddr,
|
||||||
IN const char* alias,
|
IN const char* alias,
|
||||||
IN time_t last_modified,
|
IN time_t last_modified,
|
||||||
OUT char docURL[LINE_SIZE] );
|
OUT char docURL[LINE_SIZE]);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -81,4 +81,3 @@ int configure_urlbase( INOUT IXML_Document *doc,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* URLCONFIG_H */
|
#endif /* URLCONFIG_H */
|
||||||
|
|
||||||
|
@ -592,6 +592,7 @@ static int
|
|||||||
get_device_info( IN http_message_t *request,
|
get_device_info( IN http_message_t *request,
|
||||||
IN int isQuery,
|
IN int isQuery,
|
||||||
IN IXML_Document *actionDoc,
|
IN IXML_Document *actionDoc,
|
||||||
|
IN int AddressFamily,
|
||||||
OUT UpnpString *device_udn,
|
OUT UpnpString *device_udn,
|
||||||
OUT UpnpString *service_id,
|
OUT UpnpString *service_id,
|
||||||
OUT Upnp_FunPtr *callback,
|
OUT Upnp_FunPtr *callback,
|
||||||
@ -612,7 +613,8 @@ get_device_info( IN http_message_t *request,
|
|||||||
|
|
||||||
HandleLock();
|
HandleLock();
|
||||||
|
|
||||||
if( GetDeviceHandleInfo( &device_hnd, &device_info ) != HND_DEVICE ) {
|
if( GetDeviceHandleInfo( AddressFamily,
|
||||||
|
&device_hnd, &device_info ) != HND_DEVICE ) {
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,10 +845,10 @@ error_handler:
|
|||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static UPNP_INLINE void
|
static UPNP_INLINE void handle_query_variable(
|
||||||
handle_query_variable( IN SOCKINFO * info,
|
IN SOCKINFO *info,
|
||||||
IN http_message_t * request,
|
IN http_message_t *request,
|
||||||
IN IXML_Document * xml_doc )
|
IN IXML_Document *xml_doc )
|
||||||
{
|
{
|
||||||
UpnpStateVarRequest *variable = UpnpStateVarRequest_new();
|
UpnpStateVarRequest *variable = UpnpStateVarRequest_new();
|
||||||
Upnp_FunPtr soap_event_callback;
|
Upnp_FunPtr soap_event_callback;
|
||||||
@ -864,6 +866,7 @@ handle_query_variable( IN SOCKINFO * info,
|
|||||||
// get info for event
|
// get info for event
|
||||||
err_code = get_device_info(
|
err_code = get_device_info(
|
||||||
request, 1, xml_doc,
|
request, 1, xml_doc,
|
||||||
|
info->foreign_sockaddr.ss_family,
|
||||||
(UpnpString *)UpnpStateVarRequest_get_DevUDN(variable),
|
(UpnpString *)UpnpStateVarRequest_get_DevUDN(variable),
|
||||||
(UpnpString *)UpnpStateVarRequest_get_ServiceID(variable),
|
(UpnpString *)UpnpStateVarRequest_get_ServiceID(variable),
|
||||||
&soap_event_callback,
|
&soap_event_callback,
|
||||||
@ -876,7 +879,7 @@ handle_query_variable( IN SOCKINFO * info,
|
|||||||
|
|
||||||
UpnpStateVarRequest_set_ErrCode(variable, UPNP_E_SUCCESS);
|
UpnpStateVarRequest_set_ErrCode(variable, UPNP_E_SUCCESS);
|
||||||
UpnpStateVarRequest_strcpy_StateVarName(variable, var_name);
|
UpnpStateVarRequest_strcpy_StateVarName(variable, var_name);
|
||||||
UpnpStateVarRequest_set_CtrlPtIPAddr(variable, &info->foreign_ip_addr);
|
UpnpStateVarRequest_set_CtrlPtIPAddr(variable, &info->foreign_sockaddr);
|
||||||
|
|
||||||
// send event
|
// send event
|
||||||
soap_event_callback( UPNP_CONTROL_GET_VAR_REQUEST, variable, cookie );
|
soap_event_callback( UPNP_CONTROL_GET_VAR_REQUEST, variable, cookie );
|
||||||
@ -960,6 +963,7 @@ handle_invoke_action( IN SOCKINFO * info,
|
|||||||
request,
|
request,
|
||||||
0,
|
0,
|
||||||
xml_doc,
|
xml_doc,
|
||||||
|
info->foreign_sockaddr.ss_family,
|
||||||
devUDN,
|
devUDN,
|
||||||
serviceID,
|
serviceID,
|
||||||
&soap_event_callback,
|
&soap_event_callback,
|
||||||
@ -975,7 +979,7 @@ handle_invoke_action( IN SOCKINFO * info,
|
|||||||
UpnpActionRequest_set_DevUDN(action, devUDN);
|
UpnpActionRequest_set_DevUDN(action, devUDN);
|
||||||
UpnpActionRequest_set_ServiceID(action, serviceID);
|
UpnpActionRequest_set_ServiceID(action, serviceID);
|
||||||
UpnpActionRequest_set_ActionRequest(action, actionRequestDoc);
|
UpnpActionRequest_set_ActionRequest(action, actionRequestDoc);
|
||||||
UpnpActionRequest_set_CtrlPtIPAddr(action, &info->foreign_ip_addr);
|
UpnpActionRequest_set_CtrlPtIPAddr(action, &info->foreign_sockaddr);
|
||||||
|
|
||||||
UpnpPrintf(UPNP_INFO, SOAP, __FILE__, __LINE__, "Calling Callback\n");
|
UpnpPrintf(UPNP_INFO, SOAP, __FILE__, __LINE__, "Calling Callback\n");
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ void send_search_result(IN void *data)
|
|||||||
* Parameters:
|
* Parameters:
|
||||||
* IN http_message_t *hmsg:
|
* IN http_message_t *hmsg:
|
||||||
* SSDP message from the device
|
* SSDP message from the device
|
||||||
* IN struct sockaddr_in *dest_addr:
|
* IN struct sockaddr *dest_addr:
|
||||||
* Address of the device
|
* Address of the device
|
||||||
* IN xboolean timeout:
|
* IN xboolean timeout:
|
||||||
* timeout kept by the control point while
|
* timeout kept by the control point while
|
||||||
@ -100,9 +100,9 @@ void send_search_result(IN void *data)
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
void ssdp_handle_ctrlpt_msg(
|
void ssdp_handle_ctrlpt_msg(
|
||||||
IN http_message_t *hmsg,
|
IN http_message_t *hmsg,
|
||||||
IN struct sockaddr_in *dest_addr,
|
IN struct sockaddr *dest_addr,
|
||||||
IN xboolean timeout, // only in search reply
|
IN xboolean timeout, // only in search reply
|
||||||
IN void *cookie ) // only in search reply
|
IN void *cookie) // only in search reply
|
||||||
{
|
{
|
||||||
int handle;
|
int handle;
|
||||||
struct Handle_Info *ctrlpt_info = NULL;
|
struct Handle_Info *ctrlpt_info = NULL;
|
||||||
@ -336,50 +336,6 @@ end_ssdp_handle_ctrlpt_msg:
|
|||||||
UpnpDiscovery_delete(param);
|
UpnpDiscovery_delete(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
|
||||||
* Function : process_reply
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* IN char* request_buf: the response came from the device
|
|
||||||
* IN int buf_len: The length of the response buffer
|
|
||||||
* IN struct sockaddr_in* dest_addr: The address of the device
|
|
||||||
* IN void *cookie : cookie passed by the control point application
|
|
||||||
* at the time of sending search message
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This function processes reply recevied from a search
|
|
||||||
*
|
|
||||||
* Returns: void
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
#ifndef WIN32
|
|
||||||
#warning There are currently no uses of the function 'process_reply()' in the code.
|
|
||||||
#warning 'process_reply()' is a candidate for removal.
|
|
||||||
#else
|
|
||||||
#pragma message("There are currently no uses of the function 'process_reply()' in the code.")
|
|
||||||
#pragma message("'process_reply()' is a candidate for removal.")
|
|
||||||
#endif
|
|
||||||
static UPNP_INLINE void
|
|
||||||
process_reply( IN char *request_buf,
|
|
||||||
IN int buf_len,
|
|
||||||
IN struct sockaddr_in *dest_addr,
|
|
||||||
IN void *cookie )
|
|
||||||
{
|
|
||||||
http_parser_t parser;
|
|
||||||
|
|
||||||
parser_response_init( &parser, HTTPMETHOD_MSEARCH );
|
|
||||||
|
|
||||||
// parse
|
|
||||||
if( parser_append( &parser, request_buf, buf_len ) != PARSE_SUCCESS ) {
|
|
||||||
httpmsg_destroy( &parser.msg );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// handle reply
|
|
||||||
ssdp_handle_ctrlpt_msg( &parser.msg, dest_addr, FALSE, cookie );
|
|
||||||
|
|
||||||
// done
|
|
||||||
httpmsg_destroy( &parser.msg );
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : CreateClientRequestPacket
|
* Function : CreateClientRequestPacket
|
||||||
@ -389,6 +345,7 @@ process_reply( IN char *request_buf,
|
|||||||
* IN char *SearchTarget:Search Target
|
* IN char *SearchTarget:Search Target
|
||||||
* IN int Mx dest_addr: Number of seconds to wait to
|
* IN int Mx dest_addr: Number of seconds to wait to
|
||||||
* collect all the responses
|
* collect all the responses
|
||||||
|
* IN int AddressFamily: search address family
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates a HTTP search request packet
|
* This function creates a HTTP search request packet
|
||||||
@ -400,13 +357,18 @@ process_reply( IN char *request_buf,
|
|||||||
static void
|
static void
|
||||||
CreateClientRequestPacket( IN char *RqstBuf,
|
CreateClientRequestPacket( IN char *RqstBuf,
|
||||||
IN int Mx,
|
IN int Mx,
|
||||||
IN char *SearchTarget )
|
IN char *SearchTarget,
|
||||||
|
IN int AddressFamily )
|
||||||
{
|
{
|
||||||
char TempBuf[COMMAND_LEN];
|
char TempBuf[COMMAND_LEN];
|
||||||
|
|
||||||
strcpy( RqstBuf, "M-SEARCH * HTTP/1.1\r\n" );
|
strcpy( RqstBuf, "M-SEARCH * HTTP/1.1\r\n" );
|
||||||
|
|
||||||
sprintf( TempBuf, "HOST: %s:%d\r\n", SSDP_IP, SSDP_PORT );
|
if (AddressFamily == AF_INET) {
|
||||||
|
sprintf( TempBuf, "HOST: %s:%d\r\n", SSDP_IP, SSDP_PORT );
|
||||||
|
} else if (AddressFamily == AF_INET6) {
|
||||||
|
sprintf( TempBuf, "HOST: [%s]:%d\r\n", SSDP_IPV6_LINKLOCAL, SSDP_PORT );
|
||||||
|
}
|
||||||
strcat( RqstBuf, TempBuf );
|
strcat( RqstBuf, TempBuf );
|
||||||
strcat( RqstBuf, "MAN: \"ssdp:discover\"\r\n" );
|
strcat( RqstBuf, "MAN: \"ssdp:discover\"\r\n" );
|
||||||
|
|
||||||
@ -495,7 +457,17 @@ searchExpired( void *arg )
|
|||||||
* This cokie will be returned to application in the callback.
|
* This cokie will be returned to application in the callback.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates and send the search request for a specific URL.
|
* This function implements the search request of the discovery phase.
|
||||||
|
* A M-SEARCH request is sent on the SSDP channel for both IPv4 and
|
||||||
|
* IPv6 addresses. The search target(ST) is required and must be one of
|
||||||
|
* the following:
|
||||||
|
* - "ssdp:all" : Search for all devices and services.
|
||||||
|
* - "ssdp:rootdevice" : Search for root devices only.
|
||||||
|
* - "uuid:<device-uuid>" : Search for a particular device.
|
||||||
|
* - "urn:schemas-upnp-org:device:<deviceType:v>"
|
||||||
|
* - "urn:schemas-upnp-org:service:<serviceType:v>"
|
||||||
|
* - "urn:<domain-name>:device:<deviceType:v>"
|
||||||
|
* - "urn:<domain-name>:service:<serviceType:v>"
|
||||||
*
|
*
|
||||||
* Returns: int
|
* Returns: int
|
||||||
* 1 if successful else appropriate error
|
* 1 if successful else appropriate error
|
||||||
@ -506,18 +478,23 @@ SearchByTarget( IN int Mx,
|
|||||||
IN void *Cookie )
|
IN void *Cookie )
|
||||||
{
|
{
|
||||||
char errorBuffer[ERROR_BUFFER_LEN];
|
char errorBuffer[ERROR_BUFFER_LEN];
|
||||||
int socklen = sizeof( struct sockaddr_in );
|
int socklen = sizeof( struct sockaddr_storage );
|
||||||
int *id = NULL;
|
int *id = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
char *ReqBuf;
|
char ReqBufv4[BUFSIZE];
|
||||||
struct sockaddr_in destAddr;
|
char ReqBufv6[BUFSIZE];
|
||||||
|
struct sockaddr_storage __ss_v4;
|
||||||
|
struct sockaddr_storage __ss_v6;
|
||||||
|
struct sockaddr_in* destAddr4 = (struct sockaddr_in*)&__ss_v4;
|
||||||
|
struct sockaddr_in6* destAddr6 = (struct sockaddr_in6*)&__ss_v6;
|
||||||
fd_set wrSet;
|
fd_set wrSet;
|
||||||
SsdpSearchArg *newArg = NULL;
|
SsdpSearchArg *newArg = NULL;
|
||||||
int timeTillRead = 0;
|
int timeTillRead = 0;
|
||||||
int handle;
|
int handle;
|
||||||
struct Handle_Info *ctrlpt_info = NULL;
|
struct Handle_Info *ctrlpt_info = NULL;
|
||||||
enum SsdpSearchType requestType;
|
enum SsdpSearchType requestType;
|
||||||
unsigned long addr = inet_addr( LOCAL_HOST );
|
unsigned long addrv4 = inet_addr( gIF_IPV4 );
|
||||||
|
int max_fd = 0;
|
||||||
|
|
||||||
//ThreadData *ThData;
|
//ThreadData *ThData;
|
||||||
ThreadPoolJob job;
|
ThreadPoolJob job;
|
||||||
@ -527,12 +504,7 @@ SearchByTarget( IN int Mx,
|
|||||||
return UPNP_E_INVALID_PARAM;
|
return UPNP_E_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReqBuf = (char *)malloc( BUFSIZE );
|
UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, "Inside SearchByTarget\n");
|
||||||
if( ReqBuf == NULL ) {
|
|
||||||
return UPNP_E_OUTOF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, ">>> SSDP SEND >>>\n");
|
|
||||||
|
|
||||||
timeTillRead = Mx;
|
timeTillRead = Mx;
|
||||||
|
|
||||||
@ -542,21 +514,24 @@ SearchByTarget( IN int Mx,
|
|||||||
timeTillRead = MAX_SEARCH_TIME;
|
timeTillRead = MAX_SEARCH_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateClientRequestPacket( ReqBuf, timeTillRead, St );
|
CreateClientRequestPacket( ReqBufv4, timeTillRead, St, AF_INET );
|
||||||
memset( ( char * )&destAddr, 0, sizeof( struct sockaddr_in ) );
|
CreateClientRequestPacket( ReqBufv6, timeTillRead, St, AF_INET6 );
|
||||||
|
|
||||||
destAddr.sin_family = AF_INET;
|
memset( &__ss_v4, 0, sizeof( __ss_v4 ) );
|
||||||
destAddr.sin_addr.s_addr = inet_addr( SSDP_IP );
|
destAddr4->sin_family = AF_INET;
|
||||||
destAddr.sin_port = htons( SSDP_PORT );
|
inet_pton( AF_INET, SSDP_IP, &destAddr4->sin_addr );
|
||||||
|
destAddr4->sin_port = htons( SSDP_PORT );
|
||||||
|
|
||||||
FD_ZERO( &wrSet );
|
memset( &__ss_v6, 0, sizeof( __ss_v6 ) );
|
||||||
FD_SET( gSsdpReqSocket, &wrSet );
|
destAddr6->sin6_family = AF_INET6;
|
||||||
|
inet_pton( AF_INET6, SSDP_IPV6_LINKLOCAL, &destAddr6->sin6_addr );
|
||||||
|
destAddr6->sin6_port = htons( SSDP_PORT );
|
||||||
|
destAddr6->sin6_scope_id = gIF_INDEX;
|
||||||
|
|
||||||
// add search criteria to list
|
// add search criteria to list
|
||||||
HandleLock();
|
HandleLock();
|
||||||
if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
|
if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
|
||||||
HandleUnlock();
|
HandleUnlock();
|
||||||
free( ReqBuf );
|
|
||||||
return UPNP_E_INTERNAL_ERROR;
|
return UPNP_E_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,34 +553,56 @@ SearchByTarget( IN int Mx,
|
|||||||
ListAddTail( &ctrlpt_info->SsdpSearchList, newArg );
|
ListAddTail( &ctrlpt_info->SsdpSearchList, newArg );
|
||||||
HandleUnlock();
|
HandleUnlock();
|
||||||
|
|
||||||
ret = setsockopt( gSsdpReqSocket, IPPROTO_IP, IP_MULTICAST_IF,
|
FD_ZERO( &wrSet );
|
||||||
(char *)&addr, sizeof (addr) );
|
if( gSsdpReqSocket4 != INVALID_SOCKET ) {
|
||||||
|
setsockopt( gSsdpReqSocket4, IPPROTO_IP, IP_MULTICAST_IF,
|
||||||
|
(char *)&addrv4, sizeof (addrv4) );
|
||||||
|
FD_SET( gSsdpReqSocket4, &wrSet );
|
||||||
|
max_fd = max(max_fd, gSsdpReqSocket4);
|
||||||
|
}
|
||||||
|
if( gSsdpReqSocket6 != INVALID_SOCKET ) {
|
||||||
|
setsockopt( gSsdpReqSocket6, IPPROTO_IPV6, IPV6_MULTICAST_IF,
|
||||||
|
(char *)&gIF_INDEX, sizeof(gIF_INDEX) );
|
||||||
|
FD_SET( gSsdpReqSocket6, &wrSet );
|
||||||
|
max_fd = max(max_fd, gSsdpReqSocket6);
|
||||||
|
}
|
||||||
|
|
||||||
ret = select( gSsdpReqSocket + 1, NULL, &wrSet, NULL, NULL );
|
ret = select( max_fd + 1, NULL, &wrSet, NULL, NULL );
|
||||||
if( ret == -1 ) {
|
if( ret == -1 ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||||
"SSDP_LIB: Error in select(): %s\n",
|
"SSDP_LIB: Error in select(): %s\n",
|
||||||
errorBuffer );
|
errorBuffer );
|
||||||
shutdown( gSsdpReqSocket, SD_BOTH );
|
shutdown( gSsdpReqSocket4, SD_BOTH );
|
||||||
UpnpCloseSocket( gSsdpReqSocket );
|
UpnpCloseSocket( gSsdpReqSocket4 );
|
||||||
free( ReqBuf );
|
shutdown( gSsdpReqSocket6, SD_BOTH );
|
||||||
|
UpnpCloseSocket( gSsdpReqSocket6 );
|
||||||
|
|
||||||
return UPNP_E_INTERNAL_ERROR;
|
return UPNP_E_INTERNAL_ERROR;
|
||||||
} else if( FD_ISSET( gSsdpReqSocket, &wrSet ) ) {
|
}
|
||||||
|
if( gSsdpReqSocket6 != INVALID_SOCKET &&
|
||||||
|
FD_ISSET( gSsdpReqSocket6, &wrSet ) ) {
|
||||||
int NumCopy = 0;
|
int NumCopy = 0;
|
||||||
while( NumCopy < NUM_SSDP_COPY ) {
|
while( NumCopy < NUM_SSDP_COPY ) {
|
||||||
sendto( gSsdpReqSocket, ReqBuf, strlen( ReqBuf ), 0,
|
sendto( gSsdpReqSocket6, ReqBufv6, strlen( ReqBufv6 ), 0,
|
||||||
(struct sockaddr *)&destAddr, socklen );
|
(struct sockaddr *)&__ss_v6, socklen );
|
||||||
NumCopy++;
|
NumCopy++;
|
||||||
imillisleep( SSDP_PAUSE );
|
imillisleep( SSDP_PAUSE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if( gSsdpReqSocket4 != INVALID_SOCKET &&
|
||||||
|
FD_ISSET( gSsdpReqSocket4, &wrSet ) ) {
|
||||||
|
int NumCopy = 0;
|
||||||
|
while( NumCopy < NUM_SSDP_COPY ) {
|
||||||
|
sendto( gSsdpReqSocket4, ReqBufv4, strlen( ReqBufv4 ), 0,
|
||||||
|
(struct sockaddr *)&__ss_v4, socklen );
|
||||||
|
NumCopy++;
|
||||||
|
imillisleep( SSDP_PAUSE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free( ReqBuf );
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // EXCLUDE_SSDP
|
#endif // EXCLUDE_SSDP
|
||||||
#endif // INCLUDE_CLIENT_APIS
|
#endif // INCLUDE_CLIENT_APIS
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ advertiseAndReplyThread( IN void *data )
|
|||||||
|
|
||||||
AdvertiseAndReply( 0, arg->handle,
|
AdvertiseAndReply( 0, arg->handle,
|
||||||
arg->event.RequestType,
|
arg->event.RequestType,
|
||||||
&arg->dest_addr,
|
(struct sockaddr*)&arg->dest_addr,
|
||||||
arg->event.DeviceType,
|
arg->event.DeviceType,
|
||||||
arg->event.UDN,
|
arg->event.UDN,
|
||||||
arg->event.ServiceType, arg->MaxAge );
|
arg->event.ServiceType, arg->MaxAge );
|
||||||
@ -88,8 +88,8 @@ advertiseAndReplyThread( IN void *data )
|
|||||||
* Function : ssdp_handle_device_request
|
* Function : ssdp_handle_device_request
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN http_message_t* hmsg: SSDP search request from the control point
|
* IN http_message_t *hmsg: SSDP search request from the control point
|
||||||
* IN struct sockaddr_in* dest_addr: The address info of control point
|
* IN struct sockaddr *dest_addr: The address info of control point
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function handles the search request. It do the sanity checks of
|
* This function handles the search request. It do the sanity checks of
|
||||||
@ -101,8 +101,8 @@ advertiseAndReplyThread( IN void *data )
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifdef INCLUDE_DEVICE_APIS
|
#ifdef INCLUDE_DEVICE_APIS
|
||||||
void
|
void
|
||||||
ssdp_handle_device_request( IN http_message_t * hmsg,
|
ssdp_handle_device_request( IN http_message_t *hmsg,
|
||||||
IN struct sockaddr_in *dest_addr )
|
IN struct sockaddr *dest_addr )
|
||||||
{
|
{
|
||||||
#define MX_FUDGE_FACTOR 10
|
#define MX_FUDGE_FACTOR 10
|
||||||
|
|
||||||
@ -142,7 +142,8 @@ ssdp_handle_device_request( IN http_message_t * hmsg,
|
|||||||
|
|
||||||
HandleLock();
|
HandleLock();
|
||||||
// device info
|
// device info
|
||||||
if( GetDeviceHandleInfo( &handle, &dev_info ) != HND_DEVICE ) {
|
if( GetDeviceHandleInfo( dest_addr->sa_family,
|
||||||
|
&handle, &dev_info ) != HND_DEVICE ) {
|
||||||
HandleUnlock();
|
HandleUnlock();
|
||||||
return; // no info found
|
return; // no info found
|
||||||
}
|
}
|
||||||
@ -170,7 +171,7 @@ ssdp_handle_device_request( IN http_message_t * hmsg,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
threadArg->handle = handle;
|
threadArg->handle = handle;
|
||||||
threadArg->dest_addr = ( *dest_addr );
|
memcpy( &threadArg->dest_addr, dest_addr, sizeof(threadArg->dest_addr) );
|
||||||
threadArg->event = event;
|
threadArg->event = event;
|
||||||
threadArg->MaxAge = maxAge;
|
threadArg->MaxAge = maxAge;
|
||||||
|
|
||||||
@ -201,7 +202,7 @@ ssdp_handle_device_request( IN http_message_t * hmsg,
|
|||||||
* Function : NewRequestHandler
|
* Function : NewRequestHandler
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN struct sockaddr_in * DestAddr: Ip address, to send the reply.
|
* IN struct sockaddr *DestAddr: Ip address, to send the reply.
|
||||||
* IN int NumPacket: Number of packet to be sent.
|
* IN int NumPacket: Number of packet to be sent.
|
||||||
* IN char **RqPacket:Number of packet to be sent.
|
* IN char **RqPacket:Number of packet to be sent.
|
||||||
*
|
*
|
||||||
@ -213,19 +214,21 @@ ssdp_handle_device_request( IN http_message_t * hmsg,
|
|||||||
* 1 if successful else appropriate error
|
* 1 if successful else appropriate error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static int
|
static int
|
||||||
NewRequestHandler( IN struct sockaddr_in *DestAddr,
|
NewRequestHandler( IN struct sockaddr *DestAddr,
|
||||||
IN int NumPacket,
|
IN int NumPacket,
|
||||||
IN char **RqPacket )
|
IN char **RqPacket )
|
||||||
{
|
{
|
||||||
char errorBuffer[ERROR_BUFFER_LEN];
|
char errorBuffer[ERROR_BUFFER_LEN];
|
||||||
int ReplySock;
|
SOCKET ReplySock;
|
||||||
int socklen = sizeof( struct sockaddr_in );
|
int socklen = sizeof( struct sockaddr_storage );
|
||||||
int NumCopy;
|
int NumCopy;
|
||||||
int Index;
|
int Index;
|
||||||
unsigned long replyAddr = inet_addr( LOCAL_HOST );
|
unsigned long replyAddr = inet_addr( gIF_IPV4 );
|
||||||
int ttl = 4; // a/c to UPNP Spec
|
int ttl = 4; // a/c to UPNP Spec
|
||||||
|
int hops = 1;
|
||||||
|
char buf_ntop[64];
|
||||||
|
|
||||||
ReplySock = socket( AF_INET, SOCK_DGRAM, 0 );
|
ReplySock = socket( DestAddr->sa_family, SOCK_DGRAM, 0 );
|
||||||
if ( ReplySock == -1 ) {
|
if ( ReplySock == -1 ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||||
@ -234,11 +237,25 @@ NewRequestHandler( IN struct sockaddr_in *DestAddr,
|
|||||||
|
|
||||||
return UPNP_E_OUTOF_SOCKET;
|
return UPNP_E_OUTOF_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_IF,
|
if( DestAddr->sa_family == AF_INET ) {
|
||||||
(char *)&replyAddr, sizeof (replyAddr) );
|
inet_ntop(AF_INET, &((struct sockaddr_in*)DestAddr)->sin_addr,
|
||||||
setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_TTL,
|
buf_ntop, sizeof(buf_ntop));
|
||||||
(char *)&ttl, sizeof (int) );
|
setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_IF,
|
||||||
|
(char *)&replyAddr, sizeof (replyAddr) );
|
||||||
|
setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_TTL,
|
||||||
|
(char *)&ttl, sizeof (int) );
|
||||||
|
} else if( DestAddr->sa_family == AF_INET6 ) {
|
||||||
|
inet_ntop(AF_INET6, &((struct sockaddr_in6*)DestAddr)->sin6_addr,
|
||||||
|
buf_ntop, sizeof(buf_ntop));
|
||||||
|
setsockopt( ReplySock, IPPROTO_IPV6, IPV6_MULTICAST_IF,
|
||||||
|
(char *)&gIF_INDEX, sizeof(gIF_INDEX) );
|
||||||
|
setsockopt( ReplySock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
|
||||||
|
(char *)&hops, sizeof(hops) );
|
||||||
|
} else {
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Invalid destination address specified." );
|
||||||
|
}
|
||||||
|
|
||||||
for( Index = 0; Index < NumPacket; Index++ ) {
|
for( Index = 0; Index < NumPacket; Index++ ) {
|
||||||
int rc;
|
int rc;
|
||||||
@ -256,11 +273,11 @@ NewRequestHandler( IN struct sockaddr_in *DestAddr,
|
|||||||
NumCopy = 0;
|
NumCopy = 0;
|
||||||
while( NumCopy < NUM_COPY ) {
|
while( NumCopy < NUM_COPY ) {
|
||||||
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||||
">>> SSDP SEND >>>\n%s\n",
|
">>> SSDP SEND to %s >>>\n%s\n",
|
||||||
*( RqPacket + Index ) );
|
buf_ntop, *( RqPacket + Index ) );
|
||||||
rc = sendto( ReplySock, *( RqPacket + Index ),
|
rc = sendto( ReplySock, *( RqPacket + Index ),
|
||||||
strlen( *( RqPacket + Index ) ),
|
strlen( *( RqPacket + Index ) ),
|
||||||
0, ( struct sockaddr * )DestAddr, socklen );
|
0, DestAddr, socklen );
|
||||||
imillisleep( SSDP_PAUSE );
|
imillisleep( SSDP_PAUSE );
|
||||||
++NumCopy;
|
++NumCopy;
|
||||||
}
|
}
|
||||||
@ -283,6 +300,7 @@ NewRequestHandler( IN struct sockaddr_in *DestAddr,
|
|||||||
* IN char * location :Location URL.
|
* IN char * location :Location URL.
|
||||||
* IN int duration :Service duration in sec.
|
* IN int duration :Service duration in sec.
|
||||||
* OUT char** packet :Output buffer filled with HTTP statement.
|
* OUT char** packet :Output buffer filled with HTTP statement.
|
||||||
|
* IN int AddressFamily: Address family of the HTTP request.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates a HTTP request packet. Depending
|
* This function creates a HTTP request packet. Depending
|
||||||
@ -298,7 +316,8 @@ CreateServicePacket( IN int msg_type,
|
|||||||
IN char *usn,
|
IN char *usn,
|
||||||
IN char *location,
|
IN char *location,
|
||||||
IN int duration,
|
IN int duration,
|
||||||
OUT char **packet )
|
OUT char **packet,
|
||||||
|
IN int AddressFamily)
|
||||||
{
|
{
|
||||||
int ret_code;
|
int ret_code;
|
||||||
char *nts;
|
char *nts;
|
||||||
@ -315,11 +334,13 @@ CreateServicePacket( IN int msg_type,
|
|||||||
if( msg_type == MSGTYPE_REPLY ) {
|
if( msg_type == MSGTYPE_REPLY ) {
|
||||||
ret_code = http_MakeMessage(
|
ret_code = http_MakeMessage(
|
||||||
&buf, 1, 1,
|
&buf, 1, 1,
|
||||||
"R" "sdc" "D" "sc" "ssc" "S" "Xc" "ssc" "sscc",
|
"R" "sdc" "D" "sc" "ssc" "ssc" "ssc" "S" "Xc" "ssc" "sscc",
|
||||||
HTTP_OK,
|
HTTP_OK,
|
||||||
"CACHE-CONTROL: max-age=", duration,
|
"CACHE-CONTROL: max-age=", duration,
|
||||||
"EXT:",
|
"EXT:",
|
||||||
"LOCATION: ", location,
|
"LOCATION: ", location,
|
||||||
|
"OPT: ", "\"http://schemas.upnp.org/upnp/1/0/\"; ns=01",
|
||||||
|
"01-NLS: ", gUpnpSdkNLSuuid,
|
||||||
X_USER_AGENT,
|
X_USER_AGENT,
|
||||||
"ST: ", nt,
|
"ST: ", nt,
|
||||||
"USN: ", usn);
|
"USN: ", usn);
|
||||||
@ -337,14 +358,18 @@ CreateServicePacket( IN int msg_type,
|
|||||||
|
|
||||||
// NOTE: The CACHE-CONTROL and LOCATION headers are not present in
|
// NOTE: The CACHE-CONTROL and LOCATION headers are not present in
|
||||||
// a shutdown msg, but are present here for MS WinMe interop.
|
// a shutdown msg, but are present here for MS WinMe interop.
|
||||||
|
|
||||||
ret_code = http_MakeMessage(
|
ret_code = http_MakeMessage(
|
||||||
&buf, 1, 1,
|
&buf, 1, 1,
|
||||||
"Q" "sssdc" "sdc" "ssc" "ssc" "ssc" "S" "Xc" "sscc",
|
"Q" "sssdc" "sdc" "ssc" "ssc" "ssc" "ssc" "ssc" "S" "Xc" "sscc",
|
||||||
HTTPMETHOD_NOTIFY, "*", (size_t)1,
|
HTTPMETHOD_NOTIFY, "*", (size_t)1,
|
||||||
"HOST: ", SSDP_IP, ":", SSDP_PORT,
|
"HOST: ",
|
||||||
|
(AddressFamily==AF_INET) ? SSDP_IP : "[" SSDP_IPV6_LINKLOCAL "]",
|
||||||
|
":", SSDP_PORT,
|
||||||
"CACHE-CONTROL: max-age=", duration,
|
"CACHE-CONTROL: max-age=", duration,
|
||||||
"LOCATION: ", location,
|
"LOCATION: ", location,
|
||||||
|
"OPT: ", "\"http://schemas.upnp.org/upnp/1/0/\"; ns=01",
|
||||||
|
"01-NLS: ", gUpnpSdkNLSuuid,
|
||||||
"NT: ", nt,
|
"NT: ", nt,
|
||||||
"NTS: ", nts,
|
"NTS: ", nts,
|
||||||
X_USER_AGENT,
|
X_USER_AGENT,
|
||||||
@ -387,9 +412,12 @@ DeviceAdvertisement( IN char *DevType,
|
|||||||
int RootDev,
|
int RootDev,
|
||||||
char *Udn,
|
char *Udn,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration )
|
IN int Duration,
|
||||||
|
IN int AddressFamily)
|
||||||
{
|
{
|
||||||
struct sockaddr_in DestAddr;
|
struct sockaddr_storage __ss;
|
||||||
|
struct sockaddr_in* DestAddr4 = (struct sockaddr_in*)&__ss;
|
||||||
|
struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&__ss;
|
||||||
|
|
||||||
//char Mil_Nt[LINE_SIZE]
|
//char Mil_Nt[LINE_SIZE]
|
||||||
char Mil_Usn[LINE_SIZE];
|
char Mil_Usn[LINE_SIZE];
|
||||||
@ -397,11 +425,22 @@ DeviceAdvertisement( IN char *DevType,
|
|||||||
int ret_code;
|
int ret_code;
|
||||||
|
|
||||||
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||||
"In function SendDeviceAdvertisemenrt\n" );
|
"In function DeviceAdvertisement\n" );
|
||||||
|
|
||||||
DestAddr.sin_family = AF_INET;
|
memset( &__ss, 0, sizeof(__ss) );
|
||||||
DestAddr.sin_addr.s_addr = inet_addr( SSDP_IP );
|
if( AddressFamily == AF_INET ) {
|
||||||
DestAddr.sin_port = htons( SSDP_PORT );
|
DestAddr4->sin_family = AF_INET;
|
||||||
|
inet_pton( AF_INET, SSDP_IP, &DestAddr4->sin_addr );
|
||||||
|
DestAddr4->sin_port = htons( SSDP_PORT );
|
||||||
|
} else if( AddressFamily == AF_INET6 ) {
|
||||||
|
DestAddr6->sin6_family = AF_INET6;
|
||||||
|
inet_pton( AF_INET6, SSDP_IPV6_LINKLOCAL, &DestAddr6->sin6_addr );
|
||||||
|
DestAddr6->sin6_port = htons( SSDP_PORT );
|
||||||
|
DestAddr6->sin6_scope_id = gIF_INDEX;
|
||||||
|
} else {
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Invalid device address family.\n" );
|
||||||
|
}
|
||||||
|
|
||||||
msgs[0] = NULL;
|
msgs[0] = NULL;
|
||||||
msgs[1] = NULL;
|
msgs[1] = NULL;
|
||||||
@ -412,17 +451,17 @@ DeviceAdvertisement( IN char *DevType,
|
|||||||
if( RootDev ) {
|
if( RootDev ) {
|
||||||
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
|
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
|
||||||
CreateServicePacket( MSGTYPE_ADVERTISEMENT, "upnp:rootdevice",
|
CreateServicePacket( MSGTYPE_ADVERTISEMENT, "upnp:rootdevice",
|
||||||
Mil_Usn, Location, Duration, &msgs[0] );
|
Mil_Usn, Location, Duration, &msgs[0], AddressFamily );
|
||||||
}
|
}
|
||||||
// both root and sub-devices need to send these two messages
|
// both root and sub-devices need to send these two messages
|
||||||
//
|
//
|
||||||
|
|
||||||
CreateServicePacket( MSGTYPE_ADVERTISEMENT, Udn, Udn,
|
CreateServicePacket( MSGTYPE_ADVERTISEMENT, Udn, Udn,
|
||||||
Location, Duration, &msgs[1] );
|
Location, Duration, &msgs[1], AddressFamily );
|
||||||
|
|
||||||
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
|
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
|
||||||
CreateServicePacket( MSGTYPE_ADVERTISEMENT, DevType, Mil_Usn,
|
CreateServicePacket( MSGTYPE_ADVERTISEMENT, DevType, Mil_Usn,
|
||||||
Location, Duration, &msgs[2] );
|
Location, Duration, &msgs[2], AddressFamily );
|
||||||
|
|
||||||
// check error
|
// check error
|
||||||
if( ( RootDev && msgs[0] == NULL ) ||
|
if( ( RootDev && msgs[0] == NULL ) ||
|
||||||
@ -435,11 +474,11 @@ DeviceAdvertisement( IN char *DevType,
|
|||||||
// send packets
|
// send packets
|
||||||
if( RootDev ) {
|
if( RootDev ) {
|
||||||
// send 3 msg types
|
// send 3 msg types
|
||||||
ret_code = NewRequestHandler( &DestAddr, 3, &msgs[0] );
|
ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 3, &msgs[0] );
|
||||||
} else // sub-device
|
} else // sub-device
|
||||||
{
|
{
|
||||||
// send 2 msg types
|
// send 2 msg types
|
||||||
ret_code = NewRequestHandler( &DestAddr, 2, &msgs[1] );
|
ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 2, &msgs[1] );
|
||||||
}
|
}
|
||||||
|
|
||||||
// free msgs
|
// free msgs
|
||||||
@ -454,7 +493,7 @@ DeviceAdvertisement( IN char *DevType,
|
|||||||
* Function : SendReply
|
* Function : SendReply
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN struct sockaddr_in * DestAddr:destination IP address.
|
* IN struct sockaddr * DestAddr:destination IP address.
|
||||||
* IN char *DevType: Device type
|
* IN char *DevType: Device type
|
||||||
* IN int RootDev: 1 means root device 0 means embedded device.
|
* IN int RootDev: 1 means root device 0 means embedded device.
|
||||||
* IN char * Udn: Device UDN
|
* IN char * Udn: Device UDN
|
||||||
@ -470,7 +509,7 @@ DeviceAdvertisement( IN char *DevType,
|
|||||||
* UPNP_E_SUCCESS if successful else appropriate error
|
* UPNP_E_SUCCESS if successful else appropriate error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int
|
int
|
||||||
SendReply( IN struct sockaddr_in *DestAddr,
|
SendReply( IN struct sockaddr *DestAddr,
|
||||||
IN char *DevType,
|
IN char *DevType,
|
||||||
IN int RootDev,
|
IN int RootDev,
|
||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
@ -493,7 +532,7 @@ SendReply( IN struct sockaddr_in *DestAddr,
|
|||||||
|
|
||||||
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
|
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
|
||||||
CreateServicePacket( MSGTYPE_REPLY, "upnp:rootdevice",
|
CreateServicePacket( MSGTYPE_REPLY, "upnp:rootdevice",
|
||||||
Mil_Usn, Location, Duration, &msgs[0] );
|
Mil_Usn, Location, Duration, &msgs[0], DestAddr->sa_family );
|
||||||
} else {
|
} else {
|
||||||
// two msgs for embedded devices
|
// two msgs for embedded devices
|
||||||
num_msgs = 1;
|
num_msgs = 1;
|
||||||
@ -501,11 +540,11 @@ SendReply( IN struct sockaddr_in *DestAddr,
|
|||||||
//NK: FIX for extra response when someone searches by udn
|
//NK: FIX for extra response when someone searches by udn
|
||||||
if( !ByType ) {
|
if( !ByType ) {
|
||||||
CreateServicePacket( MSGTYPE_REPLY, Udn, Udn, Location,
|
CreateServicePacket( MSGTYPE_REPLY, Udn, Udn, Location,
|
||||||
Duration, &msgs[0] );
|
Duration, &msgs[0], DestAddr->sa_family );
|
||||||
} else {
|
} else {
|
||||||
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
|
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
|
||||||
CreateServicePacket( MSGTYPE_REPLY, DevType, Mil_Usn,
|
CreateServicePacket( MSGTYPE_REPLY, DevType, Mil_Usn,
|
||||||
Location, Duration, &msgs[0] );
|
Location, Duration, &msgs[0], DestAddr->sa_family );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,7 +570,7 @@ SendReply( IN struct sockaddr_in *DestAddr,
|
|||||||
* Function : DeviceReply
|
* Function : DeviceReply
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN struct sockaddr_in * DestAddr:destination IP address.
|
* IN struct sockaddr *DestAddr:destination IP address.
|
||||||
* IN char *DevType: Device type
|
* IN char *DevType: Device type
|
||||||
* IN int RootDev: 1 means root device 0 means embedded device.
|
* IN int RootDev: 1 means root device 0 means embedded device.
|
||||||
* IN char * Udn: Device UDN
|
* IN char * Udn: Device UDN
|
||||||
@ -545,12 +584,12 @@ SendReply( IN struct sockaddr_in *DestAddr,
|
|||||||
* UPNP_E_SUCCESS if successful else appropriate error
|
* UPNP_E_SUCCESS if successful else appropriate error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int
|
int
|
||||||
DeviceReply( IN struct sockaddr_in *DestAddr,
|
DeviceReply( IN struct sockaddr *DestAddr,
|
||||||
IN char *DevType,
|
IN char *DevType,
|
||||||
IN int RootDev,
|
IN int RootDev,
|
||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration )
|
IN int Duration)
|
||||||
{
|
{
|
||||||
char *szReq[3],
|
char *szReq[3],
|
||||||
Mil_Nt[LINE_SIZE],
|
Mil_Nt[LINE_SIZE],
|
||||||
@ -568,18 +607,18 @@ DeviceReply( IN struct sockaddr_in *DestAddr,
|
|||||||
strcpy( Mil_Nt, "upnp:rootdevice" );
|
strcpy( Mil_Nt, "upnp:rootdevice" );
|
||||||
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
|
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
|
||||||
CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
|
CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
|
||||||
Location, Duration, &szReq[0] );
|
Location, Duration, &szReq[0], DestAddr->sa_family );
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf( Mil_Nt, "%s", Udn );
|
sprintf( Mil_Nt, "%s", Udn );
|
||||||
sprintf( Mil_Usn, "%s", Udn );
|
sprintf( Mil_Usn, "%s", Udn );
|
||||||
CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
|
CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
|
||||||
Location, Duration, &szReq[1] );
|
Location, Duration, &szReq[1], DestAddr->sa_family );
|
||||||
|
|
||||||
sprintf( Mil_Nt, "%s", DevType );
|
sprintf( Mil_Nt, "%s", DevType );
|
||||||
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
|
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
|
||||||
CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
|
CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
|
||||||
Location, Duration, &szReq[2] );
|
Location, Duration, &szReq[2], DestAddr->sa_family );
|
||||||
|
|
||||||
// check error
|
// check error
|
||||||
|
|
||||||
@ -613,6 +652,7 @@ DeviceReply( IN struct sockaddr_in *DestAddr,
|
|||||||
* IN char *ServType: Service Type.
|
* IN char *ServType: Service Type.
|
||||||
* IN char * Location: Location of Device description document.
|
* IN char * Location: Location of Device description document.
|
||||||
* IN int Duration :Life time of this device.
|
* IN int Duration :Life time of this device.
|
||||||
|
* IN int AddressFamily: Device address family
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates the advertisement packet based
|
* This function creates the advertisement packet based
|
||||||
* on the input parameter, and send it to the multicast channel.
|
* on the input parameter, and send it to the multicast channel.
|
||||||
@ -624,28 +664,42 @@ int
|
|||||||
ServiceAdvertisement( IN char *Udn,
|
ServiceAdvertisement( IN char *Udn,
|
||||||
IN char *ServType,
|
IN char *ServType,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration )
|
IN int Duration,
|
||||||
|
IN int AddressFamily)
|
||||||
{
|
{
|
||||||
char Mil_Usn[LINE_SIZE];
|
char Mil_Usn[LINE_SIZE];
|
||||||
char *szReq[1];
|
char *szReq[1];
|
||||||
struct sockaddr_in DestAddr;
|
|
||||||
int RetVal;
|
int RetVal;
|
||||||
|
struct sockaddr_storage __ss;
|
||||||
|
struct sockaddr_in* DestAddr4 = (struct sockaddr_in*)&__ss;
|
||||||
|
struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&__ss;
|
||||||
|
|
||||||
DestAddr.sin_family = AF_INET;
|
memset( &__ss, 0, sizeof(__ss) );
|
||||||
DestAddr.sin_addr.s_addr = inet_addr( SSDP_IP );
|
if( AddressFamily == AF_INET ) {
|
||||||
DestAddr.sin_port = htons( SSDP_PORT );
|
DestAddr4->sin_family = AF_INET;
|
||||||
|
inet_pton( AF_INET, SSDP_IP, &DestAddr4->sin_addr );
|
||||||
|
DestAddr4->sin_port = htons( SSDP_PORT );
|
||||||
|
} else if( AddressFamily == AF_INET6 ) {
|
||||||
|
DestAddr6->sin6_family = AF_INET6;
|
||||||
|
inet_pton( AF_INET6, SSDP_IPV6_LINKLOCAL, &DestAddr6->sin6_addr );
|
||||||
|
DestAddr6->sin6_port = htons( SSDP_PORT );
|
||||||
|
DestAddr6->sin6_scope_id = gIF_INDEX;
|
||||||
|
} else {
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Invalid device address family.\n" );
|
||||||
|
}
|
||||||
|
|
||||||
sprintf( Mil_Usn, "%s::%s", Udn, ServType );
|
sprintf( Mil_Usn, "%s::%s", Udn, ServType );
|
||||||
|
|
||||||
//CreateServiceRequestPacket(1,szReq[0],Mil_Nt,Mil_Usn,
|
//CreateServiceRequestPacket(1,szReq[0],Mil_Nt,Mil_Usn,
|
||||||
//Server,Location,Duration);
|
//Server,Location,Duration);
|
||||||
CreateServicePacket( MSGTYPE_ADVERTISEMENT, ServType, Mil_Usn,
|
CreateServicePacket( MSGTYPE_ADVERTISEMENT, ServType, Mil_Usn,
|
||||||
Location, Duration, &szReq[0] );
|
Location, Duration, &szReq[0], AddressFamily );
|
||||||
if( szReq[0] == NULL ) {
|
if( szReq[0] == NULL ) {
|
||||||
return UPNP_E_OUTOF_MEMORY;
|
return UPNP_E_OUTOF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
RetVal = NewRequestHandler( &DestAddr, 1, szReq );
|
RetVal = NewRequestHandler( (struct sockaddr*)&__ss, 1, szReq );
|
||||||
|
|
||||||
free( szReq[0] );
|
free( szReq[0] );
|
||||||
return RetVal;
|
return RetVal;
|
||||||
@ -655,7 +709,7 @@ ServiceAdvertisement( IN char *Udn,
|
|||||||
* Function : ServiceReply
|
* Function : ServiceReply
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN struct sockaddr_in *DestAddr:
|
* IN struct sockaddr *DestAddr:
|
||||||
* IN char * Udn: Device UDN
|
* IN char * Udn: Device UDN
|
||||||
* IN char *ServType: Service Type.
|
* IN char *ServType: Service Type.
|
||||||
* IN char * Location: Location of Device description document.
|
* IN char * Location: Location of Device description document.
|
||||||
@ -668,7 +722,7 @@ ServiceAdvertisement( IN char *Udn,
|
|||||||
* UPNP_E_SUCCESS if successful else appropriate error
|
* UPNP_E_SUCCESS if successful else appropriate error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int
|
int
|
||||||
ServiceReply( IN struct sockaddr_in *DestAddr,
|
ServiceReply( IN struct sockaddr *DestAddr,
|
||||||
IN char *ServType,
|
IN char *ServType,
|
||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
@ -683,7 +737,7 @@ ServiceReply( IN struct sockaddr_in *DestAddr,
|
|||||||
sprintf( Mil_Usn, "%s::%s", Udn, ServType );
|
sprintf( Mil_Usn, "%s::%s", Udn, ServType );
|
||||||
|
|
||||||
CreateServicePacket( MSGTYPE_REPLY, ServType, Mil_Usn,
|
CreateServicePacket( MSGTYPE_REPLY, ServType, Mil_Usn,
|
||||||
Location, Duration, &szReq[0] );
|
Location, Duration, &szReq[0], DestAddr->sa_family );
|
||||||
if( szReq[0] == NULL ) {
|
if( szReq[0] == NULL ) {
|
||||||
return UPNP_E_OUTOF_MEMORY;
|
return UPNP_E_OUTOF_MEMORY;
|
||||||
}
|
}
|
||||||
@ -702,6 +756,7 @@ ServiceReply( IN struct sockaddr_in *DestAddr,
|
|||||||
* IN char *ServType: Service Type.
|
* IN char *ServType: Service Type.
|
||||||
* IN char * Location: Location of Device description document.
|
* IN char * Location: Location of Device description document.
|
||||||
* IN int Duration :Service duration in sec.
|
* IN int Duration :Service duration in sec.
|
||||||
|
* IN int AddressFamily: Device address family
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates a HTTP service shutdown request packet
|
* This function creates a HTTP service shutdown request packet
|
||||||
* and sent it to the multicast channel through RequestHandler.
|
* and sent it to the multicast channel through RequestHandler.
|
||||||
@ -713,27 +768,41 @@ int
|
|||||||
ServiceShutdown( IN char *Udn,
|
ServiceShutdown( IN char *Udn,
|
||||||
IN char *ServType,
|
IN char *ServType,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration )
|
IN int Duration,
|
||||||
|
IN int AddressFamily)
|
||||||
{
|
{
|
||||||
char Mil_Usn[LINE_SIZE];
|
char Mil_Usn[LINE_SIZE];
|
||||||
char *szReq[1];
|
char *szReq[1];
|
||||||
struct sockaddr_in DestAddr;
|
struct sockaddr_storage __ss;
|
||||||
|
struct sockaddr_in* DestAddr4 = (struct sockaddr_in*)&__ss;
|
||||||
|
struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&__ss;
|
||||||
int RetVal;
|
int RetVal;
|
||||||
|
|
||||||
DestAddr.sin_family = AF_INET;
|
memset( &__ss, 0, sizeof(__ss) );
|
||||||
DestAddr.sin_addr.s_addr = inet_addr( SSDP_IP );
|
if( AddressFamily == AF_INET ) {
|
||||||
DestAddr.sin_port = htons( SSDP_PORT );
|
DestAddr4->sin_family = AF_INET;
|
||||||
|
inet_pton( AF_INET, SSDP_IP, &DestAddr4->sin_addr );
|
||||||
|
DestAddr4->sin_port = htons( SSDP_PORT );
|
||||||
|
} else if( AddressFamily == AF_INET6 ) {
|
||||||
|
DestAddr6->sin6_family = AF_INET6;
|
||||||
|
inet_pton( AF_INET6, SSDP_IPV6_LINKLOCAL, &DestAddr6->sin6_addr );
|
||||||
|
DestAddr6->sin6_port = htons( SSDP_PORT );
|
||||||
|
DestAddr6->sin6_scope_id = gIF_INDEX;
|
||||||
|
} else {
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Invalid device address family.\n" );
|
||||||
|
}
|
||||||
|
|
||||||
//sprintf(Mil_Nt,"%s",ServType);
|
//sprintf(Mil_Nt,"%s",ServType);
|
||||||
sprintf( Mil_Usn, "%s::%s", Udn, ServType );
|
sprintf( Mil_Usn, "%s::%s", Udn, ServType );
|
||||||
//CreateServiceRequestPacket(0,szReq[0],Mil_Nt,Mil_Usn,
|
//CreateServiceRequestPacket(0,szReq[0],Mil_Nt,Mil_Usn,
|
||||||
//Server,Location,Duration);
|
//Server,Location,Duration);
|
||||||
CreateServicePacket( MSGTYPE_SHUTDOWN, ServType, Mil_Usn,
|
CreateServicePacket( MSGTYPE_SHUTDOWN, ServType, Mil_Usn,
|
||||||
Location, Duration, &szReq[0] );
|
Location, Duration, &szReq[0], AddressFamily );
|
||||||
if( szReq[0] == NULL ) {
|
if( szReq[0] == NULL ) {
|
||||||
return UPNP_E_OUTOF_MEMORY;
|
return UPNP_E_OUTOF_MEMORY;
|
||||||
}
|
}
|
||||||
RetVal = NewRequestHandler( &DestAddr, 1, szReq );
|
RetVal = NewRequestHandler( (struct sockaddr*)&__ss, 1, szReq );
|
||||||
|
|
||||||
free( szReq[0] );
|
free( szReq[0] );
|
||||||
return RetVal;
|
return RetVal;
|
||||||
@ -748,6 +817,7 @@ ServiceShutdown( IN char *Udn,
|
|||||||
* IN char * Udn: Device UDN
|
* IN char * Udn: Device UDN
|
||||||
* IN char * Location: Location URL
|
* IN char * Location: Location URL
|
||||||
* IN int Duration :Device duration in sec.
|
* IN int Duration :Device duration in sec.
|
||||||
|
* IN int AddressFamily: Device address family.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates a HTTP device shutdown request packet
|
* This function creates a HTTP device shutdown request packet
|
||||||
@ -762,9 +832,12 @@ DeviceShutdown( IN char *DevType,
|
|||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *_Server,
|
IN char *_Server,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration )
|
IN int Duration,
|
||||||
|
IN int AddressFamily)
|
||||||
{
|
{
|
||||||
struct sockaddr_in DestAddr;
|
struct sockaddr_storage __ss;
|
||||||
|
struct sockaddr_in* DestAddr4 = (struct sockaddr_in*)&__ss;
|
||||||
|
struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&__ss;
|
||||||
char *msgs[3];
|
char *msgs[3];
|
||||||
char Mil_Usn[LINE_SIZE];
|
char Mil_Usn[LINE_SIZE];
|
||||||
int ret_code;
|
int ret_code;
|
||||||
@ -773,26 +846,37 @@ DeviceShutdown( IN char *DevType,
|
|||||||
msgs[1] = NULL;
|
msgs[1] = NULL;
|
||||||
msgs[2] = NULL;
|
msgs[2] = NULL;
|
||||||
|
|
||||||
DestAddr.sin_family = AF_INET;
|
memset( &__ss, 0, sizeof(__ss) );
|
||||||
DestAddr.sin_addr.s_addr = inet_addr( SSDP_IP );
|
if( AddressFamily == AF_INET ) {
|
||||||
DestAddr.sin_port = htons( SSDP_PORT );
|
DestAddr4->sin_family = AF_INET;
|
||||||
|
inet_pton( AF_INET, SSDP_IP, &DestAddr4->sin_addr );
|
||||||
|
DestAddr4->sin_port = htons( SSDP_PORT );
|
||||||
|
} else if( AddressFamily == AF_INET6 ) {
|
||||||
|
DestAddr6->sin6_family = AF_INET6;
|
||||||
|
inet_pton( AF_INET6, SSDP_IPV6_LINKLOCAL, &DestAddr6->sin6_addr );
|
||||||
|
DestAddr6->sin6_port = htons( SSDP_PORT );
|
||||||
|
DestAddr6->sin6_scope_id = gIF_INDEX;
|
||||||
|
} else {
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Invalid device address family.\n" );
|
||||||
|
}
|
||||||
|
|
||||||
// root device has one extra msg
|
// root device has one extra msg
|
||||||
if( RootDev ) {
|
if( RootDev ) {
|
||||||
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
|
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
|
||||||
CreateServicePacket( MSGTYPE_SHUTDOWN, "upnp:rootdevice",
|
CreateServicePacket( MSGTYPE_SHUTDOWN, "upnp:rootdevice",
|
||||||
Mil_Usn, Location, Duration, &msgs[0] );
|
Mil_Usn, Location, Duration, &msgs[0], AddressFamily );
|
||||||
}
|
}
|
||||||
|
|
||||||
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||||
"In function DeviceShutdown\n" );
|
"In function DeviceShutdown\n" );
|
||||||
// both root and sub-devices need to send these two messages
|
// both root and sub-devices need to send these two messages
|
||||||
CreateServicePacket( MSGTYPE_SHUTDOWN, Udn, Udn,
|
CreateServicePacket( MSGTYPE_SHUTDOWN, Udn, Udn,
|
||||||
Location, Duration, &msgs[1] );
|
Location, Duration, &msgs[1], AddressFamily );
|
||||||
|
|
||||||
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
|
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
|
||||||
CreateServicePacket( MSGTYPE_SHUTDOWN, DevType, Mil_Usn,
|
CreateServicePacket( MSGTYPE_SHUTDOWN, DevType, Mil_Usn,
|
||||||
Location, Duration, &msgs[2] );
|
Location, Duration, &msgs[2], AddressFamily );
|
||||||
|
|
||||||
// check error
|
// check error
|
||||||
if( ( RootDev && msgs[0] == NULL ) ||
|
if( ( RootDev && msgs[0] == NULL ) ||
|
||||||
@ -805,11 +889,11 @@ DeviceShutdown( IN char *DevType,
|
|||||||
// send packets
|
// send packets
|
||||||
if( RootDev ) {
|
if( RootDev ) {
|
||||||
// send 3 msg types
|
// send 3 msg types
|
||||||
ret_code = NewRequestHandler( &DestAddr, 3, &msgs[0] );
|
ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 3, &msgs[0] );
|
||||||
} else // sub-device
|
} else // sub-device
|
||||||
{
|
{
|
||||||
// send 2 msg types
|
// send 2 msg types
|
||||||
ret_code = NewRequestHandler( &DestAddr, 2, &msgs[1] );
|
ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 2, &msgs[1] );
|
||||||
}
|
}
|
||||||
|
|
||||||
// free msgs
|
// free msgs
|
||||||
|
@ -42,27 +42,25 @@
|
|||||||
#include "httpparser.h"
|
#include "httpparser.h"
|
||||||
#include "httpreadwrite.h"
|
#include "httpreadwrite.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <string.h>
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#include "unixutil.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_TIME_TOREAD 45
|
#define MAX_TIME_TOREAD 45
|
||||||
|
|
||||||
CLIENTONLY( SOCKET gSsdpReqSocket = 0; )
|
CLIENTONLY( SOCKET gSsdpReqSocket4 = INVALID_SOCKET; )
|
||||||
|
CLIENTONLY( SOCKET gSsdpReqSocket6 = INVALID_SOCKET; )
|
||||||
|
|
||||||
void RequestHandler();
|
void RequestHandler();
|
||||||
|
int create_ssdp_sock_v4( SOCKET* ssdpSock );
|
||||||
|
int create_ssdp_sock_v6( SOCKET* ssdpSock );
|
||||||
|
#if INCLUDE_CLIENT_APIS
|
||||||
|
int create_ssdp_sock_reqv4( SOCKET* ssdpReqSock );
|
||||||
|
int create_ssdp_sock_reqv6( SOCKET* ssdpReqSock );
|
||||||
|
#endif
|
||||||
Event ErrotEvt;
|
Event ErrotEvt;
|
||||||
|
|
||||||
enum Listener { Idle, Stopping, Running };
|
enum Listener { Idle, Stopping, Running };
|
||||||
|
|
||||||
unsigned short ssdpStopPort;
|
|
||||||
|
|
||||||
struct SSDPSockArray {
|
struct SSDPSockArray {
|
||||||
// socket for incoming advertisments and search requests
|
// socket for incoming advertisments and search requests
|
||||||
int ssdpSock;
|
SOCKET ssdpSock;
|
||||||
// socket for sending search requests and receiving search replies
|
// socket for sending search requests and receiving search replies
|
||||||
CLIENTONLY( int ssdpReqSock; )
|
CLIENTONLY( int ssdpReqSock; )
|
||||||
};
|
};
|
||||||
@ -80,10 +78,10 @@ struct SSDPSockArray {
|
|||||||
* 1 = Send Advertisement
|
* 1 = Send Advertisement
|
||||||
* IN UpnpDevice_Handle Hnd: Device handle
|
* IN UpnpDevice_Handle Hnd: Device handle
|
||||||
* IN enum SsdpSearchType SearchType:Search type for sending replies
|
* 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 *DeviceType:Device type
|
||||||
* IN char *DeviceUDN:Device UDN
|
* IN char *DeviceUDN:Device UDN
|
||||||
* IN char *ServiceType:Service type
|
* IN char *ServiceType:Service type
|
||||||
* IN int Exp:Advertisement age
|
* IN int Exp:Advertisement age
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
@ -95,7 +93,7 @@ struct SSDPSockArray {
|
|||||||
int AdvertiseAndReply( IN int AdFlag,
|
int AdvertiseAndReply( IN int AdFlag,
|
||||||
IN UpnpDevice_Handle Hnd,
|
IN UpnpDevice_Handle Hnd,
|
||||||
IN enum SsdpSearchType SearchType,
|
IN enum SsdpSearchType SearchType,
|
||||||
IN struct sockaddr_in *DestAddr,
|
IN struct sockaddr *DestAddr,
|
||||||
IN char *DeviceType,
|
IN char *DeviceType,
|
||||||
IN char *DeviceUDN,
|
IN char *DeviceUDN,
|
||||||
IN char *ServiceType,
|
IN char *ServiceType,
|
||||||
@ -234,10 +232,10 @@ int AdvertiseAndReply( IN int AdFlag,
|
|||||||
// send the device advertisement
|
// send the device advertisement
|
||||||
if( AdFlag == 1 ) {
|
if( AdFlag == 1 ) {
|
||||||
DeviceAdvertisement( devType, i == 0,
|
DeviceAdvertisement( devType, i == 0,
|
||||||
UDNstr, SInfo->DescURL, Exp );
|
UDNstr, SInfo->DescURL, Exp, SInfo->DeviceAf );
|
||||||
} else { // AdFlag == -1
|
} else { // AdFlag == -1
|
||||||
DeviceShutdown( devType, i == 0, UDNstr,
|
DeviceShutdown( devType, i == 0, UDNstr,
|
||||||
SERVER, SInfo->DescURL, Exp );
|
SERVER, SInfo->DescURL, Exp, SInfo->DeviceAf );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch ( SearchType ) {
|
switch ( SearchType ) {
|
||||||
@ -353,10 +351,10 @@ int AdvertiseAndReply( IN int AdFlag,
|
|||||||
if( AdFlag ) {
|
if( AdFlag ) {
|
||||||
if( AdFlag == 1 ) {
|
if( AdFlag == 1 ) {
|
||||||
ServiceAdvertisement( UDNstr, servType,
|
ServiceAdvertisement( UDNstr, servType,
|
||||||
SInfo->DescURL, Exp );
|
SInfo->DescURL, Exp, SInfo->DeviceAf );
|
||||||
} else { // AdFlag == -1
|
} else { // AdFlag == -1
|
||||||
ServiceShutdown( UDNstr, servType,
|
ServiceShutdown( UDNstr, servType,
|
||||||
SInfo->DescURL, Exp );
|
SInfo->DescURL, Exp, SInfo->DeviceAf );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch ( SearchType ) {
|
switch ( SearchType ) {
|
||||||
@ -403,7 +401,7 @@ int AdvertiseAndReply( IN int AdFlag,
|
|||||||
* Function : Make_Socket_NoBlocking
|
* Function : Make_Socket_NoBlocking
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN int sock: socket
|
* IN SOCKET sock: socket
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function makes socket non-blocking.
|
* This function makes socket non-blocking.
|
||||||
@ -412,7 +410,7 @@ int AdvertiseAndReply( IN int AdFlag,
|
|||||||
* 0 if successful else -1
|
* 0 if successful else -1
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int
|
int
|
||||||
Make_Socket_NoBlocking( int sock )
|
Make_Socket_NoBlocking( SOCKET sock )
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
u_long val=1;
|
u_long val=1;
|
||||||
@ -655,8 +653,11 @@ valid_ssdp_msg( IN http_message_t * hmsg )
|
|||||||
}
|
}
|
||||||
// check HOST header
|
// check HOST header
|
||||||
if( ( httpmsg_find_hdr( hmsg, HDR_HOST, &hdr_value ) == NULL ) ||
|
if( ( httpmsg_find_hdr( hmsg, HDR_HOST, &hdr_value ) == NULL ) ||
|
||||||
( memptr_cmp( &hdr_value, "239.255.255.250:1900" ) != 0 )
|
( ( memptr_cmp( &hdr_value, "239.255.255.250:1900" ) != 0 ) &&
|
||||||
|
( memptr_cmp( &hdr_value, "[FF02::C]:1900" ) != 0 ) )
|
||||||
) {
|
) {
|
||||||
|
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||||
|
"Invalid HOST header from SSDP message\n" );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -705,7 +706,7 @@ start_event_handler( void *Data )
|
|||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
// check msg
|
// check msg
|
||||||
if( !valid_ssdp_msg( &parser->msg ) ) {
|
if( valid_ssdp_msg( &parser->msg ) != TRUE ) {
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
return 0; //////// done; thread will free 'data'
|
return 0; //////// done; thread will free 'data'
|
||||||
@ -740,9 +741,10 @@ ssdp_event_handler_thread( void *the_data )
|
|||||||
// send msg to device or ctrlpt
|
// send msg to device or ctrlpt
|
||||||
if( ( hmsg->method == HTTPMETHOD_NOTIFY ) ||
|
if( ( hmsg->method == HTTPMETHOD_NOTIFY ) ||
|
||||||
( hmsg->request_method == HTTPMETHOD_MSEARCH ) ) {
|
( hmsg->request_method == HTTPMETHOD_MSEARCH ) ) {
|
||||||
CLIENTONLY( ssdp_handle_ctrlpt_msg( hmsg, &data->dest_addr, FALSE, NULL );)
|
CLIENTONLY( ssdp_handle_ctrlpt_msg( hmsg,
|
||||||
|
(struct sockaddr*)&data->dest_addr, FALSE, NULL );)
|
||||||
} else {
|
} else {
|
||||||
ssdp_handle_device_request( hmsg, &data->dest_addr );
|
ssdp_handle_device_request( hmsg, (struct sockaddr*)&data->dest_addr );
|
||||||
}
|
}
|
||||||
|
|
||||||
// free data
|
// free data
|
||||||
@ -766,11 +768,12 @@ readFromSSDPSocket( SOCKET socket )
|
|||||||
{
|
{
|
||||||
char *requestBuf = NULL;
|
char *requestBuf = NULL;
|
||||||
char staticBuf[BUFSIZE];
|
char staticBuf[BUFSIZE];
|
||||||
struct sockaddr_in clientAddr;
|
struct sockaddr_storage __ss;
|
||||||
ThreadPoolJob job;
|
ThreadPoolJob job;
|
||||||
ssdp_thread_data *data = NULL;
|
ssdp_thread_data *data = NULL;
|
||||||
socklen_t socklen = 0;
|
socklen_t socklen = sizeof( __ss );
|
||||||
int byteReceived = 0;
|
int byteReceived = 0;
|
||||||
|
char ntop_buf[64];
|
||||||
|
|
||||||
requestBuf = staticBuf;
|
requestBuf = staticBuf;
|
||||||
|
|
||||||
@ -778,8 +781,6 @@ readFromSSDPSocket( SOCKET socket )
|
|||||||
//can't be allocated, still drain the
|
//can't be allocated, still drain the
|
||||||
//socket using a static buffer
|
//socket using a static buffer
|
||||||
|
|
||||||
socklen = sizeof( struct sockaddr_in );
|
|
||||||
|
|
||||||
data = ( ssdp_thread_data * )
|
data = ( ssdp_thread_data * )
|
||||||
malloc( sizeof( ssdp_thread_data ) );
|
malloc( sizeof( ssdp_thread_data ) );
|
||||||
|
|
||||||
@ -787,7 +788,7 @@ readFromSSDPSocket( SOCKET socket )
|
|||||||
//initialize parser
|
//initialize parser
|
||||||
|
|
||||||
#ifdef INCLUDE_CLIENT_APIS
|
#ifdef INCLUDE_CLIENT_APIS
|
||||||
if( socket == gSsdpReqSocket ) {
|
if( socket == gSsdpReqSocket4 || socket == gSsdpReqSocket6 ) {
|
||||||
parser_response_init( &data->parser, HTTPMETHOD_MSEARCH );
|
parser_response_init( &data->parser, HTTPMETHOD_MSEARCH );
|
||||||
} else {
|
} else {
|
||||||
parser_request_init( &data->parser );
|
parser_request_init( &data->parser );
|
||||||
@ -809,10 +810,18 @@ readFromSSDPSocket( SOCKET socket )
|
|||||||
}
|
}
|
||||||
byteReceived = recvfrom( socket, requestBuf,
|
byteReceived = recvfrom( socket, requestBuf,
|
||||||
BUFSIZE - 1, 0,
|
BUFSIZE - 1, 0,
|
||||||
( struct sockaddr * )&clientAddr, &socklen );
|
(struct sockaddr *)&__ss, &socklen );
|
||||||
|
|
||||||
if( byteReceived > 0 ) {
|
if( byteReceived > 0 ) {
|
||||||
requestBuf[byteReceived] = '\0';
|
requestBuf[byteReceived] = '\0';
|
||||||
|
|
||||||
|
if( __ss.ss_family == AF_INET )
|
||||||
|
inet_ntop( AF_INET, &((struct sockaddr_in*)&__ss)->sin_addr, ntop_buf, sizeof(ntop_buf) );
|
||||||
|
else if( __ss.ss_family == AF_INET6 )
|
||||||
|
inet_ntop( AF_INET6, &((struct sockaddr_in6*)&__ss)->sin6_addr, ntop_buf, sizeof(ntop_buf) );
|
||||||
|
else
|
||||||
|
strncpy( ntop_buf, "<Invalid address family>", sizeof(ntop_buf) );
|
||||||
|
|
||||||
UpnpPrintf( UPNP_INFO, SSDP,
|
UpnpPrintf( UPNP_INFO, SSDP,
|
||||||
__FILE__, __LINE__,
|
__FILE__, __LINE__,
|
||||||
"Start of received response ----------------------------------------------------\n"
|
"Start of received response ----------------------------------------------------\n"
|
||||||
@ -820,7 +829,7 @@ readFromSSDPSocket( SOCKET socket )
|
|||||||
"End of received response ------------------------------------------------------\n"
|
"End of received response ------------------------------------------------------\n"
|
||||||
"From host %s\n",
|
"From host %s\n",
|
||||||
requestBuf,
|
requestBuf,
|
||||||
inet_ntoa( clientAddr.sin_addr ) );
|
ntop_buf );
|
||||||
UpnpPrintf( UPNP_PACKET, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_PACKET, SSDP, __FILE__, __LINE__,
|
||||||
"Start of received multicast packet --------------------------------------------\n"
|
"Start of received multicast packet --------------------------------------------\n"
|
||||||
"%s\n"
|
"%s\n"
|
||||||
@ -831,7 +840,7 @@ readFromSSDPSocket( SOCKET socket )
|
|||||||
data->parser.msg.msg.length += byteReceived;
|
data->parser.msg.msg.length += byteReceived;
|
||||||
// null-terminate
|
// null-terminate
|
||||||
data->parser.msg.msg.buf[byteReceived] = 0;
|
data->parser.msg.msg.buf[byteReceived] = 0;
|
||||||
data->dest_addr = clientAddr;
|
memcpy( &data->dest_addr, &__ss, sizeof(__ss) );
|
||||||
TPJobInit( &job, ( start_routine )
|
TPJobInit( &job, ( start_routine )
|
||||||
ssdp_event_handler_thread, data );
|
ssdp_event_handler_thread, data );
|
||||||
TPJobSetFreeFunction( &job, free_ssdp_event_handler_data );
|
TPJobSetFreeFunction( &job, free_ssdp_event_handler_data );
|
||||||
@ -846,132 +855,261 @@ readFromSSDPSocket( SOCKET socket )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : get_ssdp_sockets
|
* Function : get_ssdp_sockets
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* OUT MiniServerSockArray *out: Arrays of SSDP sockets
|
* OUT MiniServerSockArray *out: Array of SSDP sockets
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates the ssdp sockets. It set their option to listen
|
* This function creates the IPv4 and IPv6 ssdp sockets required by the
|
||||||
* for multicast traffic.
|
* control point and device operation.
|
||||||
*
|
*
|
||||||
* Returns: int
|
* Returns: int
|
||||||
* return UPNP_E_SUCCESS if successful else returns appropriate error
|
* return UPNP_E_SUCCESS if successful else returns appropriate error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int
|
int get_ssdp_sockets( MiniServerSockArray * out )
|
||||||
get_ssdp_sockets( MiniServerSockArray * out )
|
|
||||||
{
|
{
|
||||||
char errorBuffer[ERROR_BUFFER_LEN];
|
int retVal;
|
||||||
int onOff = 1;
|
|
||||||
u_char ttl = 4;
|
|
||||||
struct ip_mreq ssdpMcastAddr;
|
|
||||||
struct sockaddr_in ssdpAddr;
|
|
||||||
int option = 1;
|
|
||||||
int ret = 0;
|
|
||||||
struct in_addr addr;
|
|
||||||
SOCKET ssdpSock;
|
|
||||||
#if INCLUDE_CLIENT_APIS
|
#if INCLUDE_CLIENT_APIS
|
||||||
SOCKET ssdpReqSock;
|
// Create the IPv4 socket for SSDP REQUESTS
|
||||||
|
if( strlen( gIF_IPV4 ) > 0 ) {
|
||||||
ssdpReqSock = socket( AF_INET, SOCK_DGRAM, 0 );
|
retVal = create_ssdp_sock_reqv4( &out->ssdpReqSock4 );
|
||||||
if ( ssdpReqSock == -1 ) {
|
if( retVal != UPNP_E_SUCCESS ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
return retVal;
|
||||||
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
}
|
||||||
"Error in socket(): %s\n", errorBuffer );
|
// For use by ssdp control point.
|
||||||
|
gSsdpReqSocket4 = out->ssdpReqSock4;
|
||||||
return UPNP_E_OUTOF_SOCKET;
|
} else {
|
||||||
|
out->ssdpReqSock4 = INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the IPv6 socket for SSDP REQUESTS
|
||||||
|
if( strlen( gIF_IPV6 ) > 0 ) {
|
||||||
|
retVal = create_ssdp_sock_reqv6( &out->ssdpReqSock6 );
|
||||||
|
if( retVal != UPNP_E_SUCCESS ) {
|
||||||
|
CLIENTONLY( shutdown( out->ssdpReqSock4, SD_BOTH ); )
|
||||||
|
CLIENTONLY( UpnpCloseSocket( out->ssdpReqSock4 ); )
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
// For use by ssdp control point.
|
||||||
|
gSsdpReqSocket6 = out->ssdpReqSock6;
|
||||||
|
} else {
|
||||||
|
out->ssdpReqSock6 = INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
ret = setsockopt( ssdpReqSock, IPPROTO_IP, IP_MULTICAST_TTL,
|
|
||||||
&ttl, sizeof (ttl) );
|
|
||||||
// just do it, regardless if fails or not.
|
|
||||||
Make_Socket_NoBlocking( ssdpReqSock );
|
|
||||||
gSsdpReqSocket = ssdpReqSock;
|
|
||||||
#endif /* INCLUDE_CLIENT_APIS */
|
#endif /* INCLUDE_CLIENT_APIS */
|
||||||
|
|
||||||
ssdpSock = socket( AF_INET, SOCK_DGRAM, 0 );
|
// Create the IPv4 socket for SSDP
|
||||||
if ( ssdpSock == -1 ) {
|
if( strlen( gIF_IPV4 ) > 0 ) {
|
||||||
|
retVal = create_ssdp_sock_v4( &out->ssdpSock4 );
|
||||||
|
if( retVal != UPNP_E_SUCCESS ) {
|
||||||
|
CLIENTONLY( shutdown( out->ssdpReqSock4, SD_BOTH ); )
|
||||||
|
CLIENTONLY( UpnpCloseSocket( out->ssdpReqSock4 ); )
|
||||||
|
CLIENTONLY( shutdown( out->ssdpReqSock6, SD_BOTH ); )
|
||||||
|
CLIENTONLY( UpnpCloseSocket( out->ssdpReqSock6 ); )
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out->ssdpSock4 = INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the IPv6 socket for SSDP
|
||||||
|
if( strlen( gIF_IPV6 ) > 0 ) {
|
||||||
|
retVal = create_ssdp_sock_v6( &out->ssdpSock6 );
|
||||||
|
if( retVal != UPNP_E_SUCCESS ) {
|
||||||
|
shutdown( out->ssdpSock4, SD_BOTH );
|
||||||
|
UpnpCloseSocket( out->ssdpSock4 );
|
||||||
|
CLIENTONLY( shutdown( out->ssdpReqSock4, SD_BOTH ); )
|
||||||
|
CLIENTONLY( UpnpCloseSocket( out->ssdpReqSock4 ); )
|
||||||
|
CLIENTONLY( shutdown( out->ssdpReqSock6, SD_BOTH ); )
|
||||||
|
CLIENTONLY( UpnpCloseSocket( out->ssdpReqSock6 ); )
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out->ssdpSock6 = INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UPNP_E_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if INCLUDE_CLIENT_APIS
|
||||||
|
/************************************************************************
|
||||||
|
* Function : create_ssdp_sock_reqv4
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* IN SOCKET* ssdpReqSock: SSDP IPv4 request socket to be created
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function creates the SSDP IPv4 socket to be used by the control
|
||||||
|
* point.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* UPNP_E_SUCCESS on successful socket creation.
|
||||||
|
***************************************************************************/
|
||||||
|
int create_ssdp_sock_reqv4( SOCKET* ssdpReqSock )
|
||||||
|
{
|
||||||
|
char errorBuffer[ERROR_BUFFER_LEN];
|
||||||
|
u_char ttl = 4;
|
||||||
|
|
||||||
|
*ssdpReqSock = socket( AF_INET, SOCK_DGRAM, 0 );
|
||||||
|
if ( *ssdpReqSock == -1 ) {
|
||||||
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Error in socket(): %s\n", errorBuffer );
|
||||||
|
return UPNP_E_OUTOF_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
setsockopt( *ssdpReqSock, IPPROTO_IP, IP_MULTICAST_TTL,
|
||||||
|
&ttl, sizeof (ttl) );
|
||||||
|
|
||||||
|
// just do it, regardless if fails or not.
|
||||||
|
Make_Socket_NoBlocking( *ssdpReqSock );
|
||||||
|
|
||||||
|
return UPNP_E_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Function : create_ssdp_sock_reqv6
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* IN SOCKET* ssdpReqSock: SSDP IPv6 request socket to be created
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function creates the SSDP IPv6 socket to be used by the control
|
||||||
|
* point.
|
||||||
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
int create_ssdp_sock_reqv6( SOCKET* ssdpReqSock )
|
||||||
|
{
|
||||||
|
char errorBuffer[ERROR_BUFFER_LEN];
|
||||||
|
char hops = 1;
|
||||||
|
|
||||||
|
*ssdpReqSock = socket( AF_INET6, SOCK_DGRAM, 0 );
|
||||||
|
if ( *ssdpReqSock == -1 ) {
|
||||||
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Error in socket(): %s\n", errorBuffer );
|
||||||
|
return UPNP_E_OUTOF_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MUST use scoping of IPv6 addresses to control the propagation os SSDP
|
||||||
|
// messages instead of relying on the Hop Limit (Equivalent to the TTL
|
||||||
|
// limit in IPv4).
|
||||||
|
setsockopt( *ssdpReqSock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
|
||||||
|
&hops, sizeof(hops) );
|
||||||
|
|
||||||
|
// just do it, regardless if fails or not.
|
||||||
|
Make_Socket_NoBlocking( *ssdpReqSock );
|
||||||
|
|
||||||
|
return UPNP_E_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_CLIENT_APIS */
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Function : create_ssdp_sock_v4
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* IN SOCKET* ssdpSock: SSDP IPv4 socket to be created
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function ...
|
||||||
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
int create_ssdp_sock_v4( SOCKET* ssdpSock )
|
||||||
|
{
|
||||||
|
char errorBuffer[ERROR_BUFFER_LEN];
|
||||||
|
int onOff;
|
||||||
|
u_char ttl = 4;
|
||||||
|
struct ip_mreq ssdpMcastAddr;
|
||||||
|
struct sockaddr_storage __ss;
|
||||||
|
struct sockaddr_in* ssdpAddr4 = (struct sockaddr_in*)&__ss;
|
||||||
|
int ret = 0;
|
||||||
|
struct in_addr addr;
|
||||||
|
|
||||||
|
|
||||||
|
*ssdpSock = socket( AF_INET, SOCK_DGRAM, 0 );
|
||||||
|
if ( *ssdpSock == -1 ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
"Error in socket(): %s\n", errorBuffer );
|
"Error in socket(): %s\n", errorBuffer );
|
||||||
CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )
|
|
||||||
CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )
|
|
||||||
|
|
||||||
return UPNP_E_OUTOF_SOCKET;
|
return UPNP_E_OUTOF_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
onOff = 1;
|
onOff = 1;
|
||||||
ret = setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEADDR,
|
ret = setsockopt( *ssdpSock, SOL_SOCKET, SO_REUSEADDR,
|
||||||
(char *)&onOff, sizeof(onOff) );
|
(char*)&onOff, sizeof(onOff) );
|
||||||
if ( ret == -1) {
|
if ( ret == -1) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
"Error in setsockopt() SO_REUSEADDR: %s\n", errorBuffer );
|
"Error in setsockopt() SO_REUSEADDR: %s\n", errorBuffer );
|
||||||
CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )
|
UpnpCloseSocket( *ssdpSock );
|
||||||
shutdown( ssdpSock, SD_BOTH );
|
|
||||||
UpnpCloseSocket( ssdpSock );
|
|
||||||
|
|
||||||
return UPNP_E_SOCKET_ERROR;
|
return UPNP_E_SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(__OSX__) || defined(__APPLE__)
|
#if defined(__FreeBSD__) || defined(__OSX__) || defined(__APPLE__)
|
||||||
ret = setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEPORT,
|
onOff = 1;
|
||||||
(char *)&onOff, sizeof (onOff) );
|
ret = setsockopt( *ssdpSock, SOL_SOCKET, SO_REUSEPORT,
|
||||||
|
(char *)&onOff, sizeof(onOff) );
|
||||||
if ( ret == -1 ) {
|
if ( ret == -1 ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
"Error in setsockopt() SO_REUSEPORT: %s\n", errorBuffer );
|
"Error in setsockopt() SO_REUSEPORT: %s\n", errorBuffer );
|
||||||
CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )
|
UpnpCloseSocket( *ssdpSock );
|
||||||
shutdown( ssdpSock, SD_BOTH );
|
|
||||||
UpnpCloseSocket( ssdpSock );
|
|
||||||
|
|
||||||
return UPNP_E_SOCKET_ERROR;
|
return UPNP_E_SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
#endif /* __FreeBSD__ */
|
#endif /* __FreeBSD__ */
|
||||||
|
|
||||||
memset( (void *)&ssdpAddr, 0, sizeof( struct sockaddr_in ) );
|
memset( &__ss, 0, sizeof( __ss ) );
|
||||||
ssdpAddr.sin_family = AF_INET;
|
ssdpAddr4->sin_family = AF_INET;
|
||||||
// ssdpAddr.sin_addr.s_addr = inet_addr(LOCAL_HOST);
|
// ssdpAddr.sin_addr.s_addr = inet_addr(gIF_IPV4);
|
||||||
ssdpAddr.sin_addr.s_addr = htonl( INADDR_ANY );
|
ssdpAddr4->sin_addr.s_addr = htonl( INADDR_ANY );
|
||||||
ssdpAddr.sin_port = htons( SSDP_PORT );
|
ssdpAddr4->sin_port = htons( SSDP_PORT );
|
||||||
ret = bind( ssdpSock, (struct sockaddr *)&ssdpAddr, sizeof (ssdpAddr) );
|
ret = bind( *ssdpSock, (struct sockaddr *)&__ss, sizeof(__ss) );
|
||||||
if ( ret == -1 ) {
|
if ( ret == -1 ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
"Error in bind(), addr=0x%08X, port=%d: %s\n",
|
"Error in bind(), addr=0x%08X, port=%d: %s\n",
|
||||||
INADDR_ANY, SSDP_PORT, errorBuffer );
|
INADDR_ANY, SSDP_PORT, errorBuffer );
|
||||||
shutdown( ssdpSock, SD_BOTH );
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
UpnpCloseSocket( ssdpSock );
|
UpnpCloseSocket( *ssdpSock );
|
||||||
CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )
|
|
||||||
CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )
|
|
||||||
|
|
||||||
return UPNP_E_SOCKET_BIND;
|
return UPNP_E_SOCKET_BIND;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset( (void *)&ssdpMcastAddr, 0, sizeof (struct ip_mreq) );
|
memset( (void *)&ssdpMcastAddr, 0, sizeof (struct ip_mreq) );
|
||||||
ssdpMcastAddr.imr_interface.s_addr = inet_addr( LOCAL_HOST );
|
ssdpMcastAddr.imr_interface.s_addr = inet_addr( gIF_IPV4 );
|
||||||
ssdpMcastAddr.imr_multiaddr.s_addr = inet_addr( SSDP_IP );
|
ssdpMcastAddr.imr_multiaddr.s_addr = inet_addr( SSDP_IP );
|
||||||
ret = setsockopt( ssdpSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
ret = setsockopt( *ssdpSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
||||||
(char *)&ssdpMcastAddr, sizeof (struct ip_mreq) );
|
(char *)&ssdpMcastAddr, sizeof(struct ip_mreq) );
|
||||||
if ( ret == -1 ) {
|
if ( ret == -1 ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
"Error in setsockopt() IP_ADD_MEMBERSHIP (join multicast group): %s\n",
|
"Error in setsockopt() IP_ADD_MEMBERSHIP (join multicast group): %s\n",
|
||||||
errorBuffer );
|
errorBuffer );
|
||||||
shutdown( ssdpSock, SD_BOTH );
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )
|
UpnpCloseSocket( *ssdpSock );
|
||||||
UpnpCloseSocket( ssdpSock );
|
|
||||||
CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )
|
|
||||||
|
|
||||||
return UPNP_E_SOCKET_ERROR;
|
return UPNP_E_SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set multicast interface. */
|
/* Set multicast interface. */
|
||||||
memset( (void *)&addr, 0, sizeof (struct in_addr) );
|
memset( (void *)&addr, 0, sizeof (struct in_addr) );
|
||||||
addr.s_addr = inet_addr(LOCAL_HOST);
|
addr.s_addr = inet_addr(gIF_IPV4);
|
||||||
ret = setsockopt(ssdpSock, IPPROTO_IP, IP_MULTICAST_IF,
|
ret = setsockopt(*ssdpSock, IPPROTO_IP, IP_MULTICAST_IF,
|
||||||
(char *)&addr, sizeof addr);
|
(char *)&addr, sizeof addr);
|
||||||
if ( ret == -1 ) {
|
if ( ret == -1 ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
@ -982,26 +1120,132 @@ get_ssdp_sockets( MiniServerSockArray * out )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* result is not checked becuase it will fail in WinMe and Win9x. */
|
/* result is not checked becuase it will fail in WinMe and Win9x. */
|
||||||
ret = setsockopt( ssdpSock, IPPROTO_IP,
|
ret = setsockopt( *ssdpSock, IPPROTO_IP,
|
||||||
IP_MULTICAST_TTL, &ttl, sizeof (ttl) );
|
IP_MULTICAST_TTL, &ttl, sizeof (ttl) );
|
||||||
|
|
||||||
ret = setsockopt( ssdpSock, SOL_SOCKET, SO_BROADCAST,
|
onOff = 1;
|
||||||
(char *)&option, sizeof (option) );
|
ret = setsockopt( *ssdpSock, SOL_SOCKET, SO_BROADCAST,
|
||||||
|
(char*)&onOff, sizeof(onOff) );
|
||||||
if( ret == -1) {
|
if( ret == -1) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
"Error in setsockopt() SO_BROADCAST (set broadcast): %s\n",
|
"Error in setsockopt() SO_BROADCAST (set broadcast): %s\n",
|
||||||
errorBuffer );
|
errorBuffer );
|
||||||
shutdown( ssdpSock, SD_BOTH );
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )
|
UpnpCloseSocket( *ssdpSock );
|
||||||
UpnpCloseSocket( ssdpSock );
|
|
||||||
CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )
|
|
||||||
|
|
||||||
return UPNP_E_NETWORK_ERROR;
|
return UPNP_E_NETWORK_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLIENTONLY( out->ssdpReqSock = ssdpReqSock; )
|
return UPNP_E_SUCCESS;
|
||||||
out->ssdpSock = ssdpSock;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Function : create_ssdp_sock_v6
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* IN SOCKET* ssdpSock: SSDP IPv6 socket to be created
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function ...
|
||||||
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
int create_ssdp_sock_v6( SOCKET* ssdpSock )
|
||||||
|
{
|
||||||
|
char errorBuffer[ERROR_BUFFER_LEN];
|
||||||
|
struct ipv6_mreq ssdpMcastAddr;
|
||||||
|
struct sockaddr_storage __ss;
|
||||||
|
struct sockaddr_in6* ssdpAddr6 = (struct sockaddr_in6*)&__ss;
|
||||||
|
int onOff;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
*ssdpSock = socket( AF_INET6, SOCK_DGRAM, 0 );
|
||||||
|
if ( *ssdpSock == -1 ) {
|
||||||
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Error in socket(): %s\n", errorBuffer );
|
||||||
|
|
||||||
|
return UPNP_E_OUTOF_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
onOff = 1;
|
||||||
|
ret = setsockopt( *ssdpSock, SOL_SOCKET, SO_REUSEADDR,
|
||||||
|
(char*)&onOff, sizeof(onOff) );
|
||||||
|
if ( ret == -1) {
|
||||||
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Error in setsockopt() SO_REUSEADDR: %s\n", errorBuffer );
|
||||||
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
|
UpnpCloseSocket( *ssdpSock );
|
||||||
|
|
||||||
|
return UPNP_E_SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__FreeBSD__) || defined(__OSX__) || defined(__APPLE__)
|
||||||
|
onOff = 1;
|
||||||
|
ret = setsockopt( *ssdpSock, SOL_SOCKET, SO_REUSEPORT,
|
||||||
|
(char*)&onOff, sizeof (onOff) );
|
||||||
|
if ( ret == -1 ) {
|
||||||
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Error in setsockopt() SO_REUSEPORT: %s\n", errorBuffer );
|
||||||
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
|
UpnpCloseSocket( *ssdpSock );
|
||||||
|
|
||||||
|
return UPNP_E_SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* __FreeBSD__ */
|
||||||
|
|
||||||
|
memset( &__ss, 0, sizeof( __ss ) );
|
||||||
|
ssdpAddr6->sin6_family = AF_INET6;
|
||||||
|
ssdpAddr6->sin6_addr = in6addr_any;
|
||||||
|
//inet_pton( AF_INET6, gIF_IPV6, &ssdpAddr6->sin6_addr );
|
||||||
|
ssdpAddr6->sin6_scope_id = gIF_INDEX;
|
||||||
|
ssdpAddr6->sin6_port = htons( SSDP_PORT );
|
||||||
|
ret = bind( *ssdpSock, (struct sockaddr *)&__ss, sizeof(__ss) );
|
||||||
|
if ( ret == -1 ) {
|
||||||
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Error in bind(), addr=0x%032lX, port=%d: %s\n",
|
||||||
|
0lu, SSDP_PORT, errorBuffer );
|
||||||
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
|
UpnpCloseSocket( *ssdpSock );
|
||||||
|
|
||||||
|
return UPNP_E_SOCKET_BIND;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset( (void *)&ssdpMcastAddr, 0, sizeof(ssdpMcastAddr) );
|
||||||
|
ssdpMcastAddr.ipv6mr_interface = gIF_INDEX;
|
||||||
|
inet_pton( AF_INET6, SSDP_IPV6_LINKLOCAL, &ssdpMcastAddr.ipv6mr_multiaddr );
|
||||||
|
ret = setsockopt( *ssdpSock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
|
||||||
|
(char *)&ssdpMcastAddr, sizeof(ssdpMcastAddr) );
|
||||||
|
if ( ret == -1 ) {
|
||||||
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Error in setsockopt() IPV6_JOIN_GROUP (join multicast group): %s\n",
|
||||||
|
errorBuffer );
|
||||||
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
|
UpnpCloseSocket( *ssdpSock );
|
||||||
|
|
||||||
|
return UPNP_E_SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
onOff = 1;
|
||||||
|
ret = setsockopt( *ssdpSock, SOL_SOCKET, SO_BROADCAST,
|
||||||
|
(char*)&onOff, sizeof(onOff) );
|
||||||
|
if( ret == -1) {
|
||||||
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Error in setsockopt() SO_BROADCAST (set broadcast): %s\n",
|
||||||
|
errorBuffer );
|
||||||
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
|
UpnpCloseSocket( *ssdpSock );
|
||||||
|
|
||||||
|
return UPNP_E_NETWORK_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
return UPNP_E_SUCCESS;
|
return UPNP_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
* Function : addrToString
|
* Function : addrToString
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* IN const struct sockaddr_in* addr ; socket address object with
|
* IN const struct sockaddr* addr ; socket address object with
|
||||||
* the IP Address and port information
|
* the IP Address and port information
|
||||||
* OUT char ipaddr_port[] ; character array which will hold the
|
* OUT char ipaddr_port[] ; character array which will hold the
|
||||||
* IP Address in a string format.
|
* IP Address in a string format.
|
||||||
@ -64,11 +64,20 @@
|
|||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
static UPNP_INLINE void
|
static UPNP_INLINE void
|
||||||
addrToString( IN const struct sockaddr_in *addr,
|
addrToString( IN const struct sockaddr *addr,
|
||||||
OUT char ipaddr_port[] )
|
OUT char ipaddr_port[] )
|
||||||
{
|
{
|
||||||
sprintf( ipaddr_port, "%s:%d", inet_ntoa( addr->sin_addr ),
|
char buf_ntop[64];
|
||||||
ntohs( addr->sin_port ) );
|
|
||||||
|
if( addr->sa_family == AF_INET ) {
|
||||||
|
struct sockaddr_in* sa4 = (struct sockaddr_in*)addr;
|
||||||
|
inet_ntop(AF_INET, &sa4->sin_addr, buf_ntop, sizeof(buf_ntop) );
|
||||||
|
sprintf( ipaddr_port, "%s:%d", buf_ntop, ntohs( sa4->sin_port ) );
|
||||||
|
} else if( addr->sa_family == AF_INET6 ) {
|
||||||
|
struct sockaddr_in6* sa6 = (struct sockaddr_in6*)addr;
|
||||||
|
inet_ntop(AF_INET6, &sa6->sin6_addr, buf_ntop, sizeof(buf_ntop) );
|
||||||
|
sprintf( ipaddr_port, "[%s]:%d", buf_ntop, ntohs( sa6->sin6_port ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -344,7 +353,7 @@ config_description_doc( INOUT IXML_Document * doc,
|
|||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* INOUT IXML_Document *doc ; IXML Description document
|
* 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
|
* providing the IP address and port information
|
||||||
* IN const char* alias ; string containing the alias
|
* IN const char* alias ; string containing the alias
|
||||||
* IN time_t last_modified ; time when the XML document was
|
* IN time_t last_modified ; time when the XML document was
|
||||||
@ -352,7 +361,7 @@ config_description_doc( INOUT IXML_Document * doc,
|
|||||||
* OUT char docURL[LINE_SIZE] ; buffer to hold the URL of the
|
* OUT char docURL[LINE_SIZE] ; buffer to hold the URL of the
|
||||||
* document.
|
* document.
|
||||||
* INOUT IXML_Document *doc:dom document whose urlbase is to be modified
|
* INOUT IXML_Document *doc:dom document whose urlbase is to be modified
|
||||||
* IN const struct sockaddr_in* serverAddr : ip address and port of
|
* IN const struct sockaddr* serverAddr : ip address and port of
|
||||||
* the miniserver
|
* the miniserver
|
||||||
* IN const char* alias : a name to be used for the temp; e.g.:"foo.xml"
|
* IN const char* alias : a name to be used for the temp; e.g.:"foo.xml"
|
||||||
* IN time_t last_modified : time
|
* IN time_t last_modified : time
|
||||||
@ -371,7 +380,7 @@ config_description_doc( INOUT IXML_Document * doc,
|
|||||||
************************************************************************/
|
************************************************************************/
|
||||||
int
|
int
|
||||||
configure_urlbase( INOUT IXML_Document * doc,
|
configure_urlbase( INOUT IXML_Document * doc,
|
||||||
IN const struct sockaddr_in *serverAddr,
|
IN const struct sockaddr *serverAddr,
|
||||||
IN const char *alias,
|
IN const char *alias,
|
||||||
IN time_t last_modified,
|
IN time_t last_modified,
|
||||||
OUT char docURL[LINE_SIZE] )
|
OUT char docURL[LINE_SIZE] )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user