Example #1
0
/**
 * This function schedules the expiration when this pinhole is created or updated
 *
 * @param pinhole The pinhole to expire
 * @return the event_id created
 */
int phv6_scheduleExpiration(struct pinholev6 *pinhole)
{
    ThreadPoolJob job;
    struct phv6_expirationEvent *event;

    event = (struct phv6_expirationEvent *)malloc(
                sizeof(struct phv6_expirationEvent));
    if(event == NULL)
    {
        return 0;
    }

    event->pinhole = pinhole;

    TPJobInit( &job, ( start_routine ) phv6_expiration, event );
    TPJobSetFreeFunction( &job, ( free_routine ) phv6_freeEvent );

    if( TimerThreadSchedule(&gExpirationTimerThread,
                            pinhole->lease_time,
                            REL_SEC,
                            &job,
                            SHORT_TERM,
                            &(event->event_id))
            != UPNP_E_SUCCESS )
    {
        free( event );
        return 0;
    }

    pinhole->event_id = event->event_id;

    return event->event_id;
}
Example #2
0
/************************************************************************
* Function : ScheduleGenaAutoRenew									
*																	
* Parameters:														
*	IN int client_handle: Handle that also contains the subscription list
*	IN int TimeOut: The time out value of the subscription
*	IN client_subscription * sub: Subscription being renewed
*
* Description:														
*	This function schedules a job to renew the subscription just before
*	time out.
*
* Returns: int
*	return GENA_E_SUCCESS if successful else returns appropriate error
***************************************************************************/
static int
ScheduleGenaAutoRenew( IN int client_handle,
                       IN int TimeOut,
                       IN client_subscription * sub )
{
    struct Upnp_Event_Subscribe *RenewEventStruct = NULL;
    upnp_timeout *RenewEvent = NULL;
    int return_code = GENA_SUCCESS;
    ThreadPoolJob job;

    if( TimeOut == UPNP_INFINITE ) {
        return GENA_SUCCESS;
    }

    RenewEventStruct = ( struct Upnp_Event_Subscribe * )malloc( sizeof
                                                                ( struct
                                                                  Upnp_Event_Subscribe ) );

    if( RenewEventStruct == NULL ) {
        return UPNP_E_OUTOF_MEMORY;
    }

    RenewEvent = ( upnp_timeout * ) malloc( sizeof( upnp_timeout ) );

    if( RenewEvent == NULL ) {
        free( RenewEventStruct );
        return UPNP_E_OUTOF_MEMORY;
    }
    //schedule expire event
    strcpy( RenewEventStruct->Sid, sub->sid );
    RenewEventStruct->ErrCode = UPNP_E_SUCCESS;
    strncpy( RenewEventStruct->PublisherUrl, sub->EventURL,
             UPNP_NAME_SIZE - 1 );
    RenewEventStruct->TimeOut = TimeOut;

    //RenewEvent->EventType=UPNP_EVENT_SUBSCRIPTION_EXPIRE;
    RenewEvent->handle = client_handle;
    RenewEvent->Event = RenewEventStruct;

    TPJobInit( &job, ( start_routine ) GenaAutoRenewSubscription,
               RenewEvent );
    TPJobSetFreeFunction( &job, ( free_routine ) free_upnp_timeout );
    TPJobSetPriority( &job, MED_PRIORITY );

    //Schedule the job
    if( ( return_code = TimerThreadSchedule( &gTimerThread,
                                             TimeOut - AUTO_RENEW_TIME,
                                             REL_SEC, &job, SHORT_TERM,
                                             &( RenewEvent->
                                                eventId ) ) ) !=
        UPNP_E_SUCCESS ) {
        free( RenewEvent );
        free( RenewEventStruct );
        return return_code;
    }

    sub->RenewEventId = RenewEvent->eventId;
    return GENA_SUCCESS;
}
Example #3
0
int SearchByTarget(int Mx, char *St, void *Cookie)
{
	char errorBuffer[ERROR_BUFFER_LEN];
	int *id = NULL;
	int ret = 0;
	char ReqBufv4[BUFSIZE];
#ifdef UPNP_ENABLE_IPV6
	char ReqBufv6[BUFSIZE];
	char ReqBufv6UlaGua[BUFSIZE];
#endif
	struct sockaddr_storage __ss_v4;
#ifdef UPNP_ENABLE_IPV6
	struct sockaddr_storage __ss_v6;
#endif
	struct sockaddr_in *destAddr4 = (struct sockaddr_in *)&__ss_v4;
#ifdef UPNP_ENABLE_IPV6
	struct sockaddr_in6 *destAddr6 = (struct sockaddr_in6 *)&__ss_v6;
#endif
	fd_set wrSet;
	SsdpSearchArg *newArg = NULL;
	int timeTillRead = 0;
	int handle;
	struct Handle_Info *ctrlpt_info = NULL;
	enum SsdpSearchType requestType;
	unsigned long addrv4 = inet_addr(gIF_IPV4);
	SOCKET max_fd = 0;
	int retVal;

	/*ThreadData *ThData; */
	ThreadPoolJob job;

	memset(&job, 0, sizeof(job));

	requestType = ssdp_request_type1(St);
	if (requestType == SSDP_SERROR)
		return UPNP_E_INVALID_PARAM;
	UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
		   "Inside SearchByTarget\n");
	timeTillRead = Mx;
	if (timeTillRead < MIN_SEARCH_TIME)
		timeTillRead = MIN_SEARCH_TIME;
	else if (timeTillRead > MAX_SEARCH_TIME)
		timeTillRead = MAX_SEARCH_TIME;
	retVal = CreateClientRequestPacket(ReqBufv4, sizeof(ReqBufv4), timeTillRead, St, AF_INET);
	if (retVal != UPNP_E_SUCCESS)
		return retVal;
#ifdef UPNP_ENABLE_IPV6
	retVal = CreateClientRequestPacket(ReqBufv6, sizeof(ReqBufv6), timeTillRead, St, AF_INET6);
	if (retVal != UPNP_E_SUCCESS)
		return retVal;
	retVal = CreateClientRequestPacketUlaGua(ReqBufv6UlaGua, sizeof(ReqBufv6UlaGua), timeTillRead, St, AF_INET6);
	if (retVal != UPNP_E_SUCCESS)
		return retVal;
#endif

	memset(&__ss_v4, 0, sizeof(__ss_v4));
	destAddr4->sin_family = (sa_family_t)AF_INET;
	inet_pton(AF_INET, SSDP_IP, &destAddr4->sin_addr);
	destAddr4->sin_port = htons(SSDP_PORT);

#ifdef UPNP_ENABLE_IPV6
	memset(&__ss_v6, 0, sizeof(__ss_v6));
	destAddr6->sin6_family = (sa_family_t)AF_INET6;
	inet_pton(AF_INET6, SSDP_IPV6_SITELOCAL, &destAddr6->sin6_addr);
	destAddr6->sin6_port = htons(SSDP_PORT);
	destAddr6->sin6_scope_id = gIF_INDEX;
#endif

	/* add search criteria to list */
	HandleLock();
	if (GetClientHandleInfo(&handle, &ctrlpt_info) != HND_CLIENT) {
		HandleUnlock();
		return UPNP_E_INTERNAL_ERROR;
	}
	newArg = (SsdpSearchArg *) malloc(sizeof(SsdpSearchArg));
	newArg->searchTarget = strdup(St);
	newArg->cookie = Cookie;
	newArg->requestType = requestType;
	id = (int *)malloc(sizeof(int));
	TPJobInit(&job, (start_routine) searchExpired, id);
	TPJobSetPriority(&job, MED_PRIORITY);
	TPJobSetFreeFunction(&job, (free_routine) free);
	/* Schedule a timeout event to remove search Arg */
	TimerThreadSchedule(&gTimerThread, timeTillRead,
			    REL_SEC, &job, SHORT_TERM, id);
	newArg->timeoutEventId = *id;
	ListAddTail(&ctrlpt_info->SsdpSearchList, newArg);
	HandleUnlock();
	/* End of lock */

	FD_ZERO(&wrSet);
	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);
	}
#ifdef UPNP_ENABLE_IPV6
	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);
	}
#endif
	ret = select(max_fd + 1, NULL, &wrSet, NULL, NULL);
	if (ret == -1) {
		strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
		UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
			   "SSDP_LIB: Error in select(): %s\n", errorBuffer);
		shutdown(gSsdpReqSocket4, SD_BOTH);
		UpnpCloseSocket(gSsdpReqSocket4);
#ifdef UPNP_ENABLE_IPV6
		shutdown(gSsdpReqSocket6, SD_BOTH);
		UpnpCloseSocket(gSsdpReqSocket6);
#endif
		return UPNP_E_INTERNAL_ERROR;
	}
#ifdef UPNP_ENABLE_IPV6
	if (gSsdpReqSocket6 != INVALID_SOCKET &&
	    FD_ISSET(gSsdpReqSocket6, &wrSet)) {
		int NumCopy = 0;

		while (NumCopy < NUM_SSDP_COPY) {
			UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
				   ">>> SSDP SEND M-SEARCH >>>\n%s\n",
				   ReqBufv6UlaGua);
			sendto(gSsdpReqSocket6,
			       ReqBufv6UlaGua, strlen(ReqBufv6UlaGua), 0,
			       (struct sockaddr *)&__ss_v6,
			       sizeof(struct sockaddr_in6));
			NumCopy++;
			imillisleep(SSDP_PAUSE);
		}
		NumCopy = 0;
		inet_pton(AF_INET6, SSDP_IPV6_LINKLOCAL, &destAddr6->sin6_addr);
		while (NumCopy < NUM_SSDP_COPY) {
			UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
				   ">>> SSDP SEND M-SEARCH >>>\n%s\n",
				   ReqBufv6);
			sendto(gSsdpReqSocket6,
			       ReqBufv6, strlen(ReqBufv6), 0,
			       (struct sockaddr *)&__ss_v6,
			       sizeof(struct sockaddr_in6));
			NumCopy++;
			imillisleep(SSDP_PAUSE);
		}
	}
#endif /* IPv6 */
	if (gSsdpReqSocket4 != INVALID_SOCKET &&
	    FD_ISSET(gSsdpReqSocket4, &wrSet)) {
		int NumCopy = 0;
		while (NumCopy < NUM_SSDP_COPY) {
			UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
				   ">>> SSDP SEND M-SEARCH >>>\n%s\n",
				   ReqBufv4);
			sendto(gSsdpReqSocket4,
			       ReqBufv4, strlen(ReqBufv4), 0,
			       (struct sockaddr *)&__ss_v4,
			       sizeof(struct sockaddr_in));
			NumCopy++;
			imillisleep(SSDP_PAUSE);
		}
	}

	return 1;
}
Example #4
0
void ssdp_handle_device_request(http_message_t *hmsg, struct sockaddr_storage *dest_addr)
{
#define MX_FUDGE_FACTOR 10
	int handle;
	struct Handle_Info *dev_info = NULL;
	memptr hdr_value;
	int mx;
	char save_char;
	SsdpEvent event;
	int ret_code;
	SsdpSearchReply *threadArg = NULL;
	ThreadPoolJob job;
	int replyTime;
	int maxAge;

	memset(&job, 0, sizeof(job));

	/* check man hdr. */
	if (httpmsg_find_hdr(hmsg, HDR_MAN, &hdr_value) == NULL ||
	    memptr_cmp(&hdr_value, "\"ssdp:discover\"") != 0)
		/* bad or missing hdr. */
		return;
	/* MX header. */
	if (httpmsg_find_hdr(hmsg, HDR_MX, &hdr_value) == NULL ||
	    (mx = raw_to_int(&hdr_value, 10)) < 0)
		return;
	/* ST header. */
	if (httpmsg_find_hdr(hmsg, HDR_ST, &hdr_value) == NULL)
		return;
	save_char = hdr_value.buf[hdr_value.length];
	hdr_value.buf[hdr_value.length] = '\0';
	ret_code = ssdp_request_type(hdr_value.buf, &event);
	/* restore. */
	hdr_value.buf[hdr_value.length] = save_char;
	if (ret_code == -1)
		/* bad ST header. */
		return;

	HandleLock();
	/* device info. */
	switch (GetDeviceHandleInfo((int)dest_addr->ss_family,
				&handle, &dev_info)) {
	case HND_DEVICE:
		break;
	default:
		HandleUnlock();
		/* no info found. */
		return;
	}
	maxAge = dev_info->MaxAge;
	HandleUnlock();

	UpnpPrintf(UPNP_PACKET, API, __FILE__, __LINE__,
		   "MAX-AGE     =  %d\n", maxAge);
	UpnpPrintf(UPNP_PACKET, API, __FILE__, __LINE__,
		   "MX     =  %d\n", event.Mx);
	UpnpPrintf(UPNP_PACKET, API, __FILE__, __LINE__,
		   "DeviceType   =  %s\n", event.DeviceType);
	UpnpPrintf(UPNP_PACKET, API, __FILE__, __LINE__,
		   "DeviceUuid   =  %s\n", event.UDN);
	UpnpPrintf(UPNP_PACKET, API, __FILE__, __LINE__,
		   "ServiceType =  %s\n", event.ServiceType);
	threadArg = (SsdpSearchReply *)malloc(sizeof(SsdpSearchReply));
	if (threadArg == NULL)
		return;
	threadArg->handle = handle;
	memcpy(&threadArg->dest_addr, dest_addr, sizeof(threadArg->dest_addr));
	threadArg->event = event;
	threadArg->MaxAge = maxAge;

	TPJobInit(&job, advertiseAndReplyThread, threadArg);
	TPJobSetFreeFunction(&job, (free_routine) free);

	/* Subtract a percentage from the mx to allow for network and processing
	 * delays (i.e. if search is for 30 seconds, respond
	 * within 0 - 27 seconds). */
	if (mx >= 2)
		mx -= MAXVAL(1, mx / MX_FUDGE_FACTOR);
	if (mx < 1)
		mx = 1;
	replyTime = rand() % mx;
	TimerThreadSchedule(&gTimerThread, replyTime, REL_SEC, &job,
			    SHORT_TERM, NULL);
}
/*!
 * \brief Schedules a job to renew the subscription just before time out.
 *
 * \return GENA_E_SUCCESS if successful, otherwise returns the appropriate
 * 	error code.
 */
static int ScheduleGenaAutoRenew(
	/*! [in] Handle that also contains the subscription list. */
	IN int client_handle,
	/*! [in] The time out value of the subscription. */
	IN int TimeOut,
	/*! [in] Subscription being renewed. */
	IN ClientSubscription *sub)
{
	struct Upnp_Event_Subscribe *RenewEventStruct = NULL;
	upnp_timeout *RenewEvent = NULL;
	int return_code = GENA_SUCCESS;
	ThreadPoolJob job;
	const UpnpString *tmpSID = UpnpClientSubscription_get_SID(sub);
	const UpnpString *tmpEventURL = UpnpClientSubscription_get_EventURL(sub);

	memset(&job, 0, sizeof(job));

	if (TimeOut == UPNP_INFINITE) {
		return_code = GENA_SUCCESS;
		goto end_function;
	}

	RenewEventStruct = (struct Upnp_Event_Subscribe *)malloc(sizeof (struct Upnp_Event_Subscribe));
	if (RenewEventStruct == NULL) {
		return_code = UPNP_E_OUTOF_MEMORY;
		goto end_function;
	}
	memset(RenewEventStruct, 0, sizeof(struct Upnp_Event_Subscribe));

	RenewEvent = (upnp_timeout *) malloc(sizeof(upnp_timeout));
	if (RenewEvent == NULL) {
		free(RenewEventStruct);
		return_code = UPNP_E_OUTOF_MEMORY;
		goto end_function;
	}
	memset(RenewEvent, 0, sizeof(upnp_timeout));

	/* schedule expire event */
	RenewEventStruct->ErrCode = UPNP_E_SUCCESS;
	RenewEventStruct->TimeOut = TimeOut;
	strncpy(RenewEventStruct->Sid, UpnpString_get_String(tmpSID),
		sizeof(RenewEventStruct->Sid) - 1);
	strncpy(RenewEventStruct->PublisherUrl,
		UpnpString_get_String(tmpEventURL), NAME_SIZE - 1);

	/* RenewEvent->EventType=UPNP_EVENT_SUBSCRIPTION_EXPIRE; */
	RenewEvent->handle = client_handle;
	RenewEvent->Event = RenewEventStruct;

	TPJobInit(&job, (start_routine) GenaAutoRenewSubscription, RenewEvent);
	TPJobSetFreeFunction(&job, (free_routine)free_upnp_timeout);
	TPJobSetPriority(&job, MED_PRIORITY);

	/* Schedule the job */
	return_code = TimerThreadSchedule(
		&gTimerThread,
		TimeOut - AUTO_RENEW_TIME,
		REL_SEC,
		&job, SHORT_TERM,
		&(RenewEvent->eventId));
	if (return_code != UPNP_E_SUCCESS) {
		free(RenewEvent);
		free(RenewEventStruct);
		goto end_function;
	}

	UpnpClientSubscription_set_RenewEventId(sub, RenewEvent->eventId);

	return_code = GENA_SUCCESS;

end_function:
	return return_code;
}