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

📄 gena_device.c

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 C
📖 第 1 页 / 共 5 页
字号:
                        free( out->URLs );
                        free( out->parsedURLs );
                        out->URLs = NULL;
                        out->parsedURLs = NULL;
                        return return_code;
                    }
                }
            }
        }
    }
    out->size = URLcount;

    return URLcount;
}

/****************************************************************************
*	Function :	gena_process_subscription_request
*
*	Parameters :
*			IN SOCKINFO *info :	socket info of the device 
*			IN http_message_t* request : SUBSCRIPTION request from the control
*										point
*
*	Description :	This function handles a subscription request from a 
*		ctrl point. The socket is not closed on return.
*
*	Return :	void
*
*	Note :
****************************************************************************/
void
gena_process_subscription_request( IN SOCKINFO * info,
                                   IN http_message_t * request )
{
    Upnp_SID temp_sid;
    int return_code = 1;
    int time_out = 1801;
    service_info *service;
    struct Upnp_Subscription_Request request_struct;
    subscription *sub;
    uuid_upnp uid;
    struct Handle_Info *handle_info;
    void *cookie;
    Upnp_FunPtr callback_fun;
    UpnpDevice_Handle device_handle;
    memptr nt_hdr;
    char *event_url_path = NULL;
    memptr callback_hdr;
    memptr timeout_hdr;

    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
                         "Subscription Request Received:\n" ) );

    if( httpmsg_find_hdr( request, HDR_NT, &nt_hdr ) == NULL ) {
        error_respond( info, HTTP_BAD_REQUEST, request );
        return;
    }  

    // check NT header
    //Windows Millenium Interoperability:
    //we accept either upnp:event, or upnp:propchange for the NT header
    if( memptr_cmp_nocase( &nt_hdr, "upnp:event" ) != 0 ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, request );
        return;
    }

    // if a SID is present then the we have a bad request
    //  "incompatible headers"
    if( httpmsg_find_hdr( request, HDR_SID, NULL ) != NULL ) {
        error_respond( info, HTTP_BAD_REQUEST, request );
        return;
    }
    //look up service by eventURL
    if( ( event_url_path = str_alloc( request->uri.pathquery.buff,
                                      request->uri.pathquery.size ) ) ==
        NULL ) {
        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
        return;
    }

    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
                         "SubscriptionRequest for event URL path: %s\n",
                         event_url_path );
         )

        HandleLock(  );

    // CURRENTLY, ONLY ONE DEVICE
    if( GetDeviceHandleInfo( &device_handle, &handle_info ) != HND_DEVICE ) {
        free( event_url_path );
        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
        HandleUnlock(  );
        return;
    }
    service = FindServiceEventURLPath( &handle_info->ServiceTable,
                                       event_url_path );
    free( event_url_path );

    if( service == NULL || !service->active ) {
        error_respond( info, HTTP_NOT_FOUND, request );
        HandleUnlock(  );
        return;
    }

    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
                         "Subscription Request: Number of Subscriptions already %d\n "
                         "Max Subscriptions allowed: %d\n",
                         service->TotalSubscriptions,
                         handle_info->MaxSubscriptions ) );

    // too many subscriptions
    if( handle_info->MaxSubscriptions != -1 &&
        service->TotalSubscriptions >= handle_info->MaxSubscriptions ) {
        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
        HandleUnlock(  );
        return;
    }
    // generate new subscription
    sub = ( subscription * ) malloc( sizeof( subscription ) );
    if( sub == NULL ) {
        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
        HandleUnlock(  );
        return;
    }
    sub->eventKey = 0;
    sub->ToSendEventKey = 0;
    sub->active = 0;
    sub->next = NULL;
    sub->DeliveryURLs.size = 0;
    sub->DeliveryURLs.URLs = NULL;
    sub->DeliveryURLs.parsedURLs = NULL;

    // check for valid callbacks
    if( httpmsg_find_hdr( request, HDR_CALLBACK, &callback_hdr ) == NULL ||
        ( return_code = create_url_list( &callback_hdr,
                                         &sub->DeliveryURLs ) ) == 0 ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, request );
        freeSubscriptionList( sub );
        HandleUnlock(  );
        return;
    }
    if( return_code == UPNP_E_OUTOF_MEMORY ) {
        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
        freeSubscriptionList( sub );
        HandleUnlock(  );
        return;
    }
    // set the timeout
    if( httpmsg_find_hdr( request, HDR_TIMEOUT, &timeout_hdr ) != NULL ) {
        if( matchstr( timeout_hdr.buf, timeout_hdr.length,
                      "%iSecond-%d%0", &time_out ) == PARSE_OK ) {
            // nothing
        } else if( memptr_cmp_nocase( &timeout_hdr, "Second-infinite" ) ==
                   0 ) {
            time_out = -1;      // infinite timeout
        } else {
            time_out = DEFAULT_TIMEOUT; // default is > 1800 seconds
        }
    }
    // replace infinite timeout with max timeout, if possible
    if( handle_info->MaxSubscriptionTimeOut != -1 ) {
        if( time_out == -1 ||
            time_out > handle_info->MaxSubscriptionTimeOut ) {
            time_out = handle_info->MaxSubscriptionTimeOut;
        }
    }
    if( time_out >= 0 ) {
        sub->expireTime = time( NULL ) + time_out;
    } else {
        sub->expireTime = 0;    // infinite time
    }

    //generate SID
    uuid_create( &uid );
    uuid_unpack( &uid, temp_sid );
    sprintf( sub->sid, "uuid:%s", temp_sid );

    // respond OK
    if( respond_ok( info, time_out, sub, request ) != UPNP_E_SUCCESS ) {
        freeSubscriptionList( sub );
        HandleUnlock(  );
        return;
    }
    //add to subscription list
    sub->next = service->subscriptionList;
    service->subscriptionList = sub;
    service->TotalSubscriptions++;

    //finally generate callback for init table dump
    request_struct.ServiceId = service->serviceId;
    request_struct.UDN = service->UDN;
    strcpy( ( char * )request_struct.Sid, sub->sid );

    //copy callback
    callback_fun = handle_info->Callback;
    cookie = handle_info->Cookie;

    HandleUnlock(  );

    //make call back with request struct
    //in the future should find a way of mainting
    //that the handle is not unregistered in the middle of a 
    //callback

    callback_fun( UPNP_EVENT_SUBSCRIPTION_REQUEST,
                  &request_struct, cookie );
}

/****************************************************************************
*	Function :	gena_process_subscription_renewal_request
*
*	Parameters :
*		IN SOCKINFO *info :	socket info of the device
*		IN http_message_t* request : subscription renewal request from the 
*									control point
*
*	Description :	This function handles a subscription renewal request 
*		from a ctrl point. The connection is not destroyed on return.
*
*	Return :	void
*
*	Note :
****************************************************************************/
void
gena_process_subscription_renewal_request( IN SOCKINFO * info,
                                           IN http_message_t * request )
{
    Upnp_SID sid;
    subscription *sub;
    int time_out = 1801;
    service_info *service;
    struct Handle_Info *handle_info;
    UpnpDevice_Handle device_handle;
    memptr temp_hdr;
    membuffer event_url_path;
    memptr timeout_hdr;

    // if a CALLBACK or NT header is present, then it is an error
    if( httpmsg_find_hdr( request, HDR_CALLBACK, NULL ) != NULL ||
        httpmsg_find_hdr( request, HDR_NT, NULL ) != NULL ) {
        error_respond( info, HTTP_BAD_REQUEST, request );
        return;
    }
    // get SID
    if( httpmsg_find_hdr( request, HDR_SID, &temp_hdr ) == NULL ||
        temp_hdr.length > SID_SIZE ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, request );
        return;
    }
    memcpy( sid, temp_hdr.buf, temp_hdr.length );
    sid[temp_hdr.length] = '\0';

    // lookup service by eventURL
    membuffer_init( &event_url_path );
    if( membuffer_append( &event_url_path, request->uri.pathquery.buff,
                          request->uri.pathquery.size ) != 0 ) {
        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
        return;
    }

    HandleLock(  );

    // CURRENTLY, ONLY SUPPORT ONE DEVICE
    if( GetDeviceHandleInfo( &device_handle, &handle_info ) != HND_DEVICE ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, request );
        membuffer_destroy( &event_url_path );
        return;
    }
    service = FindServiceEventURLPath( &handle_info->ServiceTable,
                                       event_url_path.buf );
    membuffer_destroy( &event_url_path );

    // get subscription
    if( service == NULL ||
        !service->active ||
        ( ( sub = GetSubscriptionSID( sid, service ) ) == NULL ) ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, request );
        HandleUnlock(  );
        return;
    }

    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
                         "Renew request: Number of subscriptions already: %d\n "
                         "Max Subscriptions allowed:%d\n",
                         service->TotalSubscriptions,
                         handle_info->MaxSubscriptions );
         )
        // too many subscriptions
        if( handle_info->MaxSubscriptions != -1 &&
            service->TotalSubscriptions > handle_info->MaxSubscriptions ) {
        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
        RemoveSubscriptionSID( sub->sid, service );
        HandleUnlock(  );
        return;
    }
    // set the timeout
    if( httpmsg_find_hdr( request, HDR_TIMEOUT, &timeout_hdr ) != NULL ) {
        if( matchstr( timeout_hdr.buf, timeout_hdr.length,
                      "%iSecond-%d%0", &time_out ) == PARSE_OK ) {

            //nothing

        } else if( memptr_cmp_nocase( &timeout_hdr, "Second-infinite" ) ==
                   0 ) {

            time_out = -1;      // inifinite timeout

        } else {
            time_out = DEFAULT_TIMEOUT; // default is > 1800 seconds

        }
    }

    // replace infinite timeout with max timeout, if possible
    if( handle_info->MaxSubscriptionTimeOut != -1 ) {
        if( time_out == -1 ||
            time_out > handle_info->MaxSubscriptionTimeOut ) {
            time_out = handle_info->MaxSubscriptionTimeOut;
        }
    }

    if( time_out == -1 ) {
        sub->expireTime = 0;
    } else {
        sub->expireTime = time( NULL ) + time_out;
    }

    if( respond_ok( info, time_out, sub, request ) != UPNP_E_SUCCESS ) {
        RemoveSubscriptionSID( sub->sid, service );
    }

    HandleUnlock(  );
}

/****************************************************************************
*	Function :	gena_process_unsubscribe_request
*
*	Parameters :
*			IN SOCKINFO *info :	socket info of the device
*			IN http_message_t* request : UNSUBSCRIBE request from the control 
*											point
*
*	Description : This function Handles a subscription cancellation request 
*		from a ctrl point. The connection is not destroyed on return.
*
*	Return :	void
*
*	Note :
****************************************************************************/
void
gena_process_unsubscribe_request( IN SOCKINFO * info,
                                  IN http_message_t * request )
{
    Upnp_SID sid;
    service_info *service;
    struct Handle_Info *handle_info;
    UpnpDevice_Handle device_handle;

    memptr temp_hdr;
    membuffer event_url_path;

    // if a CALLBACK or NT header is present, then it is an error
    if( httpmsg_find_hdr( request, HDR_CALLBACK, NULL ) != NULL ||
        httpmsg_find_hdr( request, HDR_NT, NULL ) != NULL ) {
        error_respond( info, HTTP_BAD_REQUEST, request );
        return;
    }
    // get SID
    if( httpmsg_find_hdr( request, HDR_SID, &temp_hdr ) == NULL ||
        temp_hdr.length > SID_SIZE ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, request );
        return;
    }
    memcpy( sid, temp_hdr.buf, temp_hdr.length );
    sid[temp_hdr.length] = '\0';

    // lookup service by eventURL
    membuffer_init( &event_url_path );
    if( membuffer_append( &event_url_path, request->uri.pathquery.buff,
                          request->uri.pathquery.size ) != 0 ) {
        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
        return;
    }

    HandleLock(  );

    // CURRENTLY, ONLY SUPPORT ONE DEVICE
    if( GetDeviceHandleInfo( &device_handle, &handle_info ) != HND_DEVICE ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, request );
        membuffer_destroy( &event_url_path );
        HandleUnlock(  );
        return;
    }
    service = FindServiceEventURLPath( &handle_info->ServiceTable,
 

⌨️ 快捷键说明

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