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

📄 ssdp_server.c

📁 Upnp开发包文件
💻 C
📖 第 1 页 / 共 3 页
字号:
    if( hmsg->method != HTTPMETHOD_NOTIFY &&        hmsg->method != HTTPMETHOD_MSEARCH        && hmsg->request_method != HTTPMETHOD_MSEARCH ) {        return FALSE;    }    if( hmsg->request_method != HTTPMETHOD_MSEARCH ) {        // check PATH == *        if( hmsg->uri.type != RELATIVE ||            strncmp( "*", hmsg->uri.pathquery.buff,                     hmsg->uri.pathquery.size ) != 0 ) {            return FALSE;        }        // check HOST header        if( ( httpmsg_find_hdr( hmsg, HDR_HOST, &hdr_value ) == NULL ) ||            ( memptr_cmp( &hdr_value, "239.255.255.250:1900" ) != 0 )             ) {            return FALSE;        }    }    return TRUE;                // passed quick check}/************************************************************************* Function : start_event_handler								*																	* Parameters:														*	IN void *the_data: ssdp_thread_data structure. This structure contains*			SSDP request message.** Description:														*	This function parses the message and dispatches it to a handler *	which handles the ssdp request msg** Returns: int*	0 if successful -1 if error***************************************************************************/static XINLINE intstart_event_handler( void *Data ){    http_parser_t *parser = NULL;    parse_status_t status;    ssdp_thread_data *data = ( ssdp_thread_data * ) Data;    parser = &data->parser;    status = parser_parse( parser );    if( status == PARSE_FAILURE ) {        if( parser->msg.method != HTTPMETHOD_NOTIFY ||            !parser->valid_ssdp_notify_hack ) {            DBGONLY( UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,                                 "SSDP recvd bad msg code = %d\n",                                 status );                 )                // ignore bad msg, or not enuf mem                goto error_handler;        }        // valid notify msg    } else if( status != PARSE_SUCCESS ) {        DBGONLY( UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,                             "SSDP recvd bad msg code = %d\n", status );             )            goto error_handler;    }    // check msg    if( !valid_ssdp_msg( &parser->msg ) ) {        goto error_handler;    }    return 0;                   //////// done; thread will free 'data'  error_handler:    free_ssdp_event_handler_data( data );    return -1;}/************************************************************************* Function : ssdp_event_handler_thread								*																	* Parameters:														*	IN void *the_data: ssdp_thread_data structure. This structure contains*			SSDP request message.** Description:														*	This function is a thread that handles SSDP requests.** Returns: void*	***************************************************************************/static voidssdp_event_handler_thread( void *the_data ){    ssdp_thread_data *data = ( ssdp_thread_data * ) the_data;    http_message_t *hmsg = &data->parser.msg;    if( start_event_handler( the_data ) != 0 ) {        return;    }    // send msg to device or ctrlpt    if( ( hmsg->method == HTTPMETHOD_NOTIFY ) ||        ( hmsg->request_method == HTTPMETHOD_MSEARCH ) ) {        CLIENTONLY( ssdp_handle_ctrlpt_msg( hmsg, &data->dest_addr,                                            FALSE, NULL );             );    } else {        DEVICEONLY( ssdp_handle_device_request( hmsg, &data->dest_addr );             );    }    // free data    free_ssdp_event_handler_data( data );}/************************************************************************* Function : readFromSSDPSocket								*																	* Parameters:														*	IN SOCKET socket: SSDP socket** Description:														*	This function reads the data from the ssdp socket.** Returns: void*	***************************************************************************/voidreadFromSSDPSocket( SOCKET socket ){    char *requestBuf = NULL;    char staticBuf[BUFSIZE];    struct sockaddr_in clientAddr;    ThreadPoolJob job;    ssdp_thread_data *data = NULL;    int socklen = 0;    int byteReceived = 0;    requestBuf = staticBuf;    //in case memory    //can't be allocated, still drain the     //socket using a static buffer    socklen = sizeof( struct sockaddr_in );    data = ( ssdp_thread_data * )        malloc( sizeof( ssdp_thread_data ) );    if( data != NULL ) {        //initialize parser#ifdef INCLUDE_CLIENT_APIS        if( socket == gSsdpReqSocket ) {            parser_response_init( &data->parser, HTTPMETHOD_MSEARCH );        } else {            parser_request_init( &data->parser );        }#else        parser_request_init( &data->parser );#endif        //set size of parser buffer        if( membuffer_set_size( &data->parser.msg.msg, BUFSIZE ) == 0 ) {            //use this as the buffer for recv            requestBuf = data->parser.msg.msg.buf;        } else {            free( data );            data = NULL;        }    }    byteReceived = recvfrom( socket, requestBuf,                             BUFSIZE - 1, 0,                             ( struct sockaddr * )&clientAddr, &socklen );    if( byteReceived > 0 ) {        requestBuf[byteReceived] = '\0';        DBGONLY( UpnpPrintf( UPNP_INFO, SSDP,                             __FILE__, __LINE__,                             "Received response !!!  "                             "%s From host %s \n",                             requestBuf,                             inet_ntoa( clientAddr.sin_addr ) );             )            DBGONLY( UpnpPrintf( UPNP_PACKET, SSDP,                                 __FILE__, __LINE__,                                 "Received multicast packet:"                                 "\n %s\n", requestBuf );             )            //add thread pool job to handle request            if( data != NULL ) {            data->parser.msg.msg.length += byteReceived;            // null-terminate            data->parser.msg.msg.buf[byteReceived] = 0;            data->dest_addr = clientAddr;            TPJobInit( &job, ( start_routine )                       ssdp_event_handler_thread, data );            TPJobSetFreeFunction( &job, free_ssdp_event_handler_data );            TPJobSetPriority( &job, MED_PRIORITY );            if( ThreadPoolAdd( &gRecvThreadPool, &job, NULL ) != 0 ) {                free_ssdp_event_handler_data( data );            }        }    } else {        free_ssdp_event_handler_data( data );    }}/************************************************************************* Function : get_ssdp_sockets								*																	* Parameters:														*	OUT MiniServerSockArray *out: Arrays of SSDP sockets** Description:														*	This function creates the ssdp sockets. It set their option to listen *	for multicast traffic.** Returns: int*	return UPNP_E_SUCCESS if successful else returns appropriate error***************************************************************************/intget_ssdp_sockets( MiniServerSockArray * out ){    SOCKET ssdpSock;    CLIENTONLY( SOCKET ssdpReqSock;         )    int onOff = 1;    u_char ttl = 4;    struct ip_mreq ssdpMcastAddr;    struct sockaddr_in ssdpAddr;    int option = 1;    CLIENTONLY( if( ( ssdpReqSock = socket( AF_INET, SOCK_DGRAM, 0 ) )                    == UPNP_INVALID_SOCKET ) {                DBGONLY( UpnpPrintf( UPNP_CRITICAL,                                     SSDP, __FILE__, __LINE__,                                     "Error in socket operation !!!\n" ); )                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 ); gSsdpReqSocket = ssdpReqSock; )  //CLIENTONLY        if( ( ssdpSock = socket( AF_INET, SOCK_DGRAM, 0 ) )            == UPNP_INVALID_SOCKET ) {            DBGONLY( UpnpPrintf( UPNP_CRITICAL,                                 SSDP, __FILE__, __LINE__,                                 "Error in socket operation !!!\n" );                 )                CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ) );            CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );            return UPNP_E_OUTOF_SOCKET;        }    onOff = 1;    if( setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEADDR,                    ( char * )&onOff, sizeof( onOff ) ) != 0 ) {        DBGONLY( UpnpPrintf( UPNP_CRITICAL,                             SSDP, __FILE__, __LINE__,                             "Error in set reuse addr !!!\n" );             )            CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ) );        CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );        shutdown( ssdpSock, SD_BOTH );        UpnpCloseSocket( ssdpSock );        return UPNP_E_SOCKET_ERROR;    }    memset( ( void * )&ssdpAddr, 0, sizeof( struct sockaddr_in ) );    ssdpAddr.sin_family = AF_INET;    //  ssdpAddr.sin_addr.s_addr = inet_addr(LOCAL_HOST);    ssdpAddr.sin_addr.s_addr = htonl( INADDR_ANY );    ssdpAddr.sin_port = htons( SSDP_PORT );    if( bind        ( ssdpSock, ( struct sockaddr * )&ssdpAddr,          sizeof( ssdpAddr ) ) != 0 ) {        DBGONLY( UpnpPrintf                 ( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,                   "Error in binding !!!\n" );             )            shutdown( ssdpSock, SD_BOTH );        UpnpCloseSocket( ssdpSock );        CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ) );        CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );        return UPNP_E_SOCKET_BIND;    }    memset( ( void * )&ssdpMcastAddr, 0, sizeof( struct ip_mreq ) );    ssdpMcastAddr.imr_interface.s_addr = htonl( INADDR_ANY );    ssdpMcastAddr.imr_multiaddr.s_addr = inet_addr( SSDP_IP );    if( setsockopt( ssdpSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,                    ( char * )&ssdpMcastAddr,                    sizeof( struct ip_mreq ) ) != 0 ) {        DBGONLY( UpnpPrintf                 ( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,                   "Error in joining" " multicast group !!!\n" );             )            shutdown( ssdpSock, SD_BOTH );        CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ) );        UpnpCloseSocket( ssdpSock );        CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );        return UPNP_E_SOCKET_ERROR;    }    // result is not checked becuase it will fail in WinMe and Win9x.    setsockopt( ssdpSock, IPPROTO_IP,                IP_MULTICAST_TTL, &ttl, sizeof( ttl ) );    if( setsockopt( ssdpSock, SOL_SOCKET, SO_BROADCAST,                    ( char * )&option, sizeof( option ) ) != 0 ) {        DBGONLY( UpnpPrintf( UPNP_CRITICAL,                             SSDP, __FILE__, __LINE__,                             "Error in setting broadcast !!!\n" );             )            shutdown( ssdpSock, SD_BOTH );        CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ) );        UpnpCloseSocket( ssdpSock );        CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );        return UPNP_E_NETWORK_ERROR;    }    CLIENTONLY( out->ssdpReqSock = ssdpReqSock;         );    out->ssdpSock = ssdpSock;    return UPNP_E_SUCCESS;}#endif // EXCLUDE_SSDP

⌨️ 快捷键说明

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