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

📄 miniserver.c

📁 Upnp开发包文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////// 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.//////////////////////////////////////////////////////////////////////////////************************************************************************* Purpose: This file implements the functionality and utility functions* used by the Miniserver module.************************************************************************/#include <arpa/inet.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/wait.h>#include <unistd.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/wait.h>#include <unistd.h>#include <arpa/inet.h>#include <netinet/in.h>#include "unixutil.h"#include "ithread.h"#include <assert.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include "ssdplib.h"#include "util.h"#include "miniserver.h"#include "ThreadPool.h"#include "httpreadwrite.h"#include "statcodes.h"#include "upnp.h"#include "upnpapi.h"#define APPLICATION_LISTENING_PORT 49152struct mserv_request_t {    int connfd;                 // connection handle    struct in_addr foreign_ip_addr;    unsigned short foreign_ip_port;};typedef enum { MSERV_IDLE, MSERV_RUNNING, MSERV_STOPPING } MiniServerState;unsigned short miniStopSockPort;////////////////////////////////////////////////////////////////////////////// module varsstatic MiniServerCallback gGetCallback = NULL;static MiniServerCallback gSoapCallback = NULL;static MiniServerCallback gGenaCallback = NULL;static MiniServerState gMServState = MSERV_IDLE;/*************************************************************************	Function :	SetHTTPGetCallback**	Parameters :*		MiniServerCallback callback ; - HTTP Callback to be invoked **	Description :	Set HTTP Get Callback**	Return :	void**	Note :************************************************************************/voidSetHTTPGetCallback( MiniServerCallback callback ){    gGetCallback = callback;}/*************************************************************************	Function :	SetSoapCallback**	Parameters :*		MiniServerCallback callback ; - SOAP Callback to be invoked **	Description :	Set SOAP Callback**	Return :	void**	Note :************************************************************************/voidSetSoapCallback( MiniServerCallback callback ){    gSoapCallback = callback;}/*************************************************************************	Function :	SetGenaCallback**	Parameters :*		MiniServerCallback callback ; - GENA Callback to be invoked**	Description :	Set GENA Callback**	Return :	void**	Note :************************************************************************/voidSetGenaCallback( MiniServerCallback callback ){    gGenaCallback = callback;}/*************************************************************************	Function :	dispatch_request**	Parameters :*		IN SOCKINFO *info ;		 Socket Information object.*		http_parser_t* hparser ; HTTP parser object.**	Description :	Based on the type pf message, appropriate callback *		is issued**	Return : int ;*		0 - On Success*		HTTP_INTERNAL_SERVER_ERROR - Callback is NULL**	Note :************************************************************************/static intdispatch_request( IN SOCKINFO * info,                  http_parser_t * hparser ){    MiniServerCallback callback;    switch ( hparser->msg.method ) {            //Soap Call        case SOAPMETHOD_POST:        case HTTPMETHOD_MPOST:            callback = gSoapCallback;            break;            //Gena Call        case HTTPMETHOD_NOTIFY:        case HTTPMETHOD_SUBSCRIBE:        case HTTPMETHOD_UNSUBSCRIBE:            DBGONLY( UpnpPrintf                     ( UPNP_INFO, MSERV, __FILE__, __LINE__,                       "miniserver %d: got GENA msg\n", info->socket );                 )                callback = gGenaCallback;            break;            //HTTP server call        case HTTPMETHOD_GET:        case HTTPMETHOD_POST:        case HTTPMETHOD_HEAD:        case HTTPMETHOD_SIMPLEGET:            callback = gGetCallback;            break;        default:            callback = NULL;    }    if( callback == NULL ) {        return HTTP_INTERNAL_SERVER_ERROR;    }    callback( hparser, &hparser->msg, info );    return 0;}/*************************************************************************	Function :	handle_error**	Parameters :*		*		IN SOCKINFO *info ;		Socket Inforamtion Object*		int http_error_code ;	HTTP Error Code*		int major ;				Major Version Number*		int minor ;				Minor Version Number**	Description :	Send Error Message**	Return : void;**	Note :************************************************************************/static XINLINE voidhandle_error( IN SOCKINFO * info,              int http_error_code,              int major,              int minor ){    http_SendStatusResponse( info, http_error_code, major, minor );}/*************************************************************************	Function :	free_handle_request_arg**	Parameters :*		void *args ; Request Message to be freed**	Description :	Free memory assigned for handling request and unitial-*	-ize socket functionality**	Return :	void**	Note :************************************************************************/static voidfree_handle_request_arg( void *args ){    struct mserv_request_t *request = ( struct mserv_request_t * )args;    shutdown( request->connfd, SD_BOTH );    UpnpCloseSocket( request->connfd );    free( request );}/*************************************************************************	Function :	handle_request**	Parameters :*		void *args ;	Request Message to be handled**	Description :	Receive the request and dispatch it for handling**	Return :	void**	Note :************************************************************************/static voidhandle_request( void *args ){    SOCKINFO info;    int http_error_code;    int ret_code;    int major = 1;    int minor = 1;    http_parser_t parser;    http_message_t *hmsg = NULL;    int timeout = HTTP_DEFAULT_TIMEOUT;    struct mserv_request_t *request = ( struct mserv_request_t * )args;    int connfd = request->connfd;    DBGONLY( UpnpPrintf             ( UPNP_INFO, MSERV, __FILE__, __LINE__,               "miniserver %d: READING\n", connfd );         )        //parser_request_init( &parser ); ////LEAK_FIX_MK        hmsg = &parser.msg;    if( sock_init_with_ip( &info, connfd, request->foreign_ip_addr,                           request->foreign_ip_port ) != UPNP_E_SUCCESS ) {        free( request );        httpmsg_destroy( hmsg );        return;    }    // read    ret_code = http_RecvMessage( &info, &parser, HTTPMETHOD_UNKNOWN,                                 &timeout, &http_error_code );    if( ret_code != 0 ) {        goto error_handler;    }    DBGONLY( UpnpPrintf             ( UPNP_INFO, MSERV, __FILE__, __LINE__,               "miniserver %d: PROCESSING...\n", connfd );         )        // dispatch        http_error_code = dispatch_request( &info, &parser );    if( http_error_code != 0 ) {        goto error_handler;    }    http_error_code = 0;  error_handler:    if( http_error_code > 0 ) {        if( hmsg ) {            major = hmsg->major_version;            minor = hmsg->minor_version;        }        handle_error( &info, http_error_code, major, minor );    }    DBGONLY( UpnpPrintf             ( UPNP_INFO, MSERV, __FILE__, __LINE__,               "miniserver %d: COMPLETE\n", connfd );         )        sock_destroy( &info, SD_BOTH ); //should shutdown completely    httpmsg_destroy( hmsg );    free( request );}/*************************************************************************	Function :	schedule_request_job**	Parameters :*		IN int connfd ;	Socket Descriptor on which connection is accepted*		IN struct sockaddr_in* clientAddr ;	Clients Address information**	Description :	Initilize the thread pool to handle a request.*		Sets priority for the job and adds the job to the thread pool***	Return :	void**	Note :************************************************************************/static XINLINE voidschedule_request_job( IN int connfd,                      IN struct sockaddr_in *clientAddr ){    struct mserv_request_t *request;    ThreadPoolJob job;    request =        ( struct mserv_request_t * )        malloc( sizeof( struct mserv_request_t ) );    if( request == NULL ) {        DBGONLY( UpnpPrintf                 ( UPNP_INFO, MSERV, __FILE__, __LINE__,                   "mserv %d: out of memory\n", connfd );             )            shutdown( request->connfd, SD_BOTH );        UpnpCloseSocket( connfd );        return;    }    request->connfd = connfd;    request->foreign_ip_addr = clientAddr->sin_addr;    request->foreign_ip_port = ntohs( clientAddr->sin_port );    TPJobInit( &job, ( start_routine ) handle_request, ( void * )request );    TPJobSetFreeFunction( &job, free_handle_request_arg );    TPJobSetPriority( &job, MED_PRIORITY );    if( ThreadPoolAdd( &gRecvThreadPool, &job, NULL ) != 0 ) {        DBGONLY( UpnpPrintf                 ( UPNP_INFO, MSERV, __FILE__, __LINE__,                   "mserv %d: cannot schedule request\n", connfd );             )            free( request );        shutdown( connfd, SD_BOTH );        UpnpCloseSocket( connfd );        return;    }}/*************************************************************************	Function :	RunMiniServer**	Parameters :*		MiniServerSockArray *miniSock ;	Socket Array**	Description :	Function runs the miniserver. The MiniServer accepts a *		new request and schedules a thread to handle the new request.*		Checks for socket state and invokes appropriate read and shutdown *		actions for the Miniserver and SSDP sockets **	Return :	void**	Note :************************************************************************/static voidRunMiniServer( MiniServerSockArray * miniSock ){    struct sockaddr_in clientAddr;    int clientLen;    SOCKET miniServSock,      connectHnd;    SOCKET miniServStopSock;    SOCKET ssdpSock;    CLIENTONLY( SOCKET ssdpReqSock;         )    fd_set expSet;    fd_set rdSet;    unsigned int maxMiniSock;    int byteReceived;    char requestBuf[256];    miniServSock = miniSock->miniServerSock;    miniServStopSock = miniSock->miniServerStopSock;    ssdpSock = miniSock->ssdpSock;    CLIENTONLY( ssdpReqSock = miniSock->ssdpReqSock;         );    gMServState = MSERV_RUNNING;    maxMiniSock = max( miniServSock, miniServStopSock );    maxMiniSock = max( maxMiniSock, ( SOCKET ) ( ssdpSock ) );    CLIENTONLY( maxMiniSock =                max( maxMiniSock, ( SOCKET ) ( ssdpReqSock ) ) );    ++maxMiniSock;    while( TRUE ) {        FD_ZERO( &rdSet );        FD_ZERO( &expSet );        FD_SET( miniServStopSock, &expSet );        FD_SET( miniServSock, &rdSet );        FD_SET( miniServStopSock, &rdSet );        FD_SET( ssdpSock, &rdSet );        CLIENTONLY( FD_SET( ssdpReqSock, &rdSet ) );        if( select( maxMiniSock, &rdSet, NULL, &expSet, NULL ) ==            UPNP_SOCKETERROR ) {            DBGONLY( UpnpPrintf

⌨️ 快捷键说明

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