⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssdp_server.c

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 C
📖 第 1 页 / 共 3 页
字号:
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation 
// All rights reserved. 
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions are met: 
//
// * Redistributions of source code must retain the above copyright notice, 
// this list of conditions and the following disclaimer. 
// * Redistributions in binary form must reproduce the above copyright notice, 
// this list of conditions and the following disclaimer in the documentation 
// and/or other materials provided with the distribution. 
// * Neither name of Intel Corporation nor the names of its contributors 
// may be used to endorse or promote products derived from this software 
// without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////

#include "config.h"
#if EXCLUDE_SSDP == 0

#ifdef _WIN32
#define strcasecmp _stricmp
#endif

#ifdef _WIN32
#define strncasecmp strnicmp
#endif

#include "membuffer.h"
#include "ssdplib.h"
#include <stdio.h>
#include "ThreadPool.h"
#include "miniserver.h"

#ifdef _WIN32
#include <winsock2.h>
#include <Ws2tcpip.h>
#endif

#include "upnpapi.h"
#include "httpparser.h"
#include "httpreadwrite.h"

#define MAX_TIME_TOREAD  45

CLIENTONLY( SOCKET gSsdpReqSocket = 0;
     )

     void RequestHandler(  );
     Event ErrotEvt;

     enum Listener { Idle, Stopping, Running };

     unsigned short ssdpStopPort;

     struct SSDPSockArray {
         int ssdpSock;          //socket for incoming advertisments and search requests
           CLIENTONLY( int ssdpReqSock;
              )                 //socket for sending search 
             //requests and receiving
             // search replies
     };

#ifdef INCLUDE_DEVICE_APIS
#if EXCLUDE_SSDP == 0

/************************************************************************
* Function : AdvertiseAndReply									
*																	
* Parameters:														
*	IN int AdFlag: -1 = Send shutdown, 0 = send reply, 
*					1 = Send Advertisement
*	IN UpnpDevice_Handle Hnd: Device handle
*	IN enum SsdpSearchType SearchType:Search type for sending replies
*	IN struct sockaddr_in *DestAddr:Destination address
*   IN char *DeviceType:Device type
*	IN char *DeviceUDN:Device UDN
*   IN char *ServiceType:Service type
*	IN int Exp:Advertisement age
*
* Description:														
*	This function sends SSDP advertisements, replies and shutdown messages.
*
* Returns: int
*	UPNP_E_SUCCESS if successful else appropriate error
***************************************************************************/
     int AdvertiseAndReply( IN int AdFlag,
                            IN UpnpDevice_Handle Hnd,
                            IN enum SsdpSearchType SearchType,
                            IN struct sockaddr_in *DestAddr,
                            IN char *DeviceType,
                            IN char *DeviceUDN,
                            IN char *ServiceType,
                            int Exp )
{
    int i,
      j;
    int defaultExp = DEFAULT_MAXAGE;
    struct Handle_Info *SInfo = NULL;
    char UDNstr[100],
      devType[100],
      servType[100];
    IXML_NodeList *nodeList = NULL;
    IXML_NodeList *tmpNodeList = NULL;
    IXML_Node *tmpNode = NULL;
    IXML_Node *tmpNode2 = NULL;
    IXML_Node *textNode = NULL;
    DOMString tmpStr;
    char SERVER[200];

    DBGONLY( const DOMString dbgStr;
             UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
                         "Inside AdvertiseAndReply with AdFlag = %d\n",
                         AdFlag ); )

        HandleLock(  );
    if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
        HandleUnlock(  );
        return UPNP_E_INVALID_HANDLE;
    }
    defaultExp = SInfo->MaxAge;

    //Modifed to prevent more than one thread from accessing the 
    //UpnpDocument stored with the handle at the same time
    // HandleUnlock();
    nodeList = NULL;

    //get server info

    get_sdk_info( SERVER, 200 );

    // parse the device list and send advertisements/replies 
    for( i = 0;; i++ ) {

        DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
                             "Entering new device list with i = %d\n\n",
                             i );
             )

            tmpNode = ixmlNodeList_item( SInfo->DeviceList, i );
        if( tmpNode == NULL ) {
            DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
                                 "Exiting new device list with i = %d\n\n",
                                 i );
                 )
                break;
        }

        DBGONLY( dbgStr = ixmlNode_getNodeName( tmpNode );
                 UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
                             "Extracting device type once for %s\n",
                             dbgStr ); )
            // extract device type 
            ixmlNodeList_free( nodeList );
        nodeList = NULL;
        nodeList =
            ixmlElement_getElementsByTagName( ( IXML_Element * ) tmpNode,
                                              "deviceType" );
        if( nodeList == NULL ) {
            continue;
        }

        DBGONLY( dbgStr = ixmlNode_getNodeName( tmpNode );
                 UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
                             "Extracting UDN for %s\n", dbgStr ); )

            DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
                                 "Extracting device type\n" );
             )

            tmpNode2 = ixmlNodeList_item( nodeList, 0 );
        if( tmpNode2 == NULL ) {
            continue;
        }
        textNode = ixmlNode_getFirstChild( tmpNode2 );
        if( textNode == NULL ) {
            continue;
        }

        DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
                             "Extracting device type \n" );
             )

            tmpStr = ixmlNode_getNodeValue( textNode );
        if( tmpStr == NULL ) {
            continue;
        }

        strcpy( devType, tmpStr );
        if( devType == NULL ) {
            continue;
        }

        DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
                             "Extracting device type = %s\n", devType );
                 if( tmpNode == NULL ) {
                 UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
                             "TempNode is NULL\n" );}
                 dbgStr = ixmlNode_getNodeName( tmpNode );
                 UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
                             "Extracting UDN for %s\n", dbgStr ); )
            // extract UDN 
            ixmlNodeList_free( nodeList );
        nodeList = NULL;
        nodeList = ixmlElement_getElementsByTagName( ( IXML_Element * )
                                                     tmpNode, "UDN" );
        if( nodeList == NULL ) {

            DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__,
                                 __LINE__, "UDN not found!!!\n" );
                 )
                continue;
        }
        tmpNode2 = ixmlNodeList_item( nodeList, 0 );
        if( tmpNode2 == NULL ) {

            DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__,
                                 __LINE__, "UDN not found!!!\n" );
                 )
                continue;
        }
        textNode = ixmlNode_getFirstChild( tmpNode2 );
        if( textNode == NULL ) {

            DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__,
                                 __LINE__, "UDN not found!!!\n" );
                 )
                continue;
        }
        tmpStr = ixmlNode_getNodeValue( textNode );
        if( tmpStr == NULL ) {
            DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
                                 "UDN not found!!!!\n" );
                 )
                continue;
        }
        strcpy( UDNstr, tmpStr );
        if( UDNstr == NULL ) {
            continue;
        }

        DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
                             "Sending UDNStr = %s \n", UDNstr );
             )
            if( AdFlag ) {
            // send the device advertisement 
            if( AdFlag == 1 ) {
                DeviceAdvertisement( devType, i == 0,
                                     UDNstr, SInfo->DescURL, Exp );
            } else              // AdFlag == -1
            {
		//printf("performing device shutdown\n");
                DeviceShutdown( devType, i == 0, UDNstr,
                                SERVER, SInfo->DescURL, Exp );
            }
        } else {
            switch ( SearchType ) {

                case SSDP_ALL:
                    DeviceReply( DestAddr,
                                 devType, i == 0,
                                 UDNstr, SInfo->DescURL, defaultExp );
                    break;

                case SSDP_ROOTDEVICE:
                    if( i == 0 ) {
                        SendReply( DestAddr, devType, 1,
                                   UDNstr, SInfo->DescURL, defaultExp, 0 );
                    }
                    break;
                case SSDP_DEVICEUDN:
                    {
                        if( DeviceUDN != NULL && strlen( DeviceUDN ) != 0 ) {
                            if( strcasecmp( DeviceUDN, UDNstr ) ) {
                                DBGONLY( UpnpPrintf
                                         ( UPNP_INFO, API, __FILE__,
                                           __LINE__,
                                           "DeviceUDN=%s and search "
                                           "UDN=%s did not match\n",
                                           UDNstr, DeviceUDN );
                                     )
                                    break;
                            } else {
                                DBGONLY( UpnpPrintf
                                         ( UPNP_INFO, API, __FILE__,
                                           __LINE__,
                                           "DeviceUDN=%s and search "
                                           "UDN=%s MATCH\n", UDNstr,
                                           DeviceUDN );
                                     )
                                    SendReply( DestAddr, devType, 0,
                                               UDNstr, SInfo->DescURL,
                                               defaultExp, 0 );
                                break;
                            }
                        }
                    }
                case SSDP_DEVICETYPE:
                    {
                        if( !strncasecmp
                            ( DeviceType, devType,
                              strlen( DeviceType ) ) ) {
                            DBGONLY( UpnpPrintf
                                     ( UPNP_INFO, API, __FILE__, __LINE__,
                                       "DeviceType=%s and search devType=%s MATCH\n",
                                       devType, DeviceType );
                                 )
                                SendReply( DestAddr, devType, 0, UDNstr,
                                           SInfo->DescURL, defaultExp, 1 );
                        }

                        DBGONLY(
                                    else
                                    UpnpPrintf( UPNP_INFO, API, __FILE__,
                                                __LINE__,
                                                "DeviceType=%s and search devType=%s"
                                                " DID NOT MATCH\n",
                                                devType, DeviceType );
                             )

                            break;
                    }
                default:
                    break;
            }
        }
        // send service advertisements for services corresponding 
        // to the same device 
        DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
                             "Sending service Advertisement\n" );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -