예제 #1
0
int AddMiniServerInterface(const char *ip, int *iface, uint16_t *listen_port4)
{
    int i;
    int error;

    ithread_mutex_lock(&gMiniServerMutex);
    for (i = 0; i < MAX_NETWORK_INTERFACES; ++i)
    {
        if (gMiniSocket->miniServerSock4[i] == INVALID_SOCKET)
            break;
    }
    if (i == MAX_NETWORK_INTERFACES)
    {
        UpnpPrintf(UPNP_CRITICAL, MSERV, __FILE__, __LINE__,
            "AddMiniServerInterface: no free interface slots");
        ithread_mutex_unlock(&gMiniServerMutex);
        return UPNP_E_OUTOF_SOCKET;
    }

    error = get_miniserver_sockets(gMiniSocket, ip, i, *listen_port4);
    if (error != UPNP_E_SUCCESS)
    {
        UpnpPrintf(UPNP_CRITICAL, MSERV, __FILE__, __LINE__,
            "AddMiniServerInterface: get_miniserver_sockets failed with error %d", error);
        ithread_mutex_unlock(&gMiniServerMutex);
        return error;
    }
    error = get_ssdp_sockets(gMiniSocket, ip, i);
    if (error != UPNP_E_SUCCESS)
    {
        UpnpPrintf(UPNP_CRITICAL, MSERV, __FILE__, __LINE__,
            "AddMiniServerInterface: get_ssdp_sockets failed with error %d", error);
        ithread_mutex_unlock(&gMiniServerMutex);
        return error;
    }

    *listen_port4 = gMiniSocket->miniServerPort4[i];
    *iface = i;
    ithread_mutex_unlock(&gMiniServerMutex);
    wake_miniserver();

    UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__,
        "AddMiniServerInterface: %s:%d added successfully to slot %d", ip, *listen_port4, i);
    return UPNP_E_SUCCESS;
}
예제 #2
0
파일: miniserver.c 프로젝트: hotgloupi/upnp
int StartMiniServer(
	/*! [in,out] Port on which the server listens for incoming IPv4
	 * connections. */
	uint16_t *listen_port4, 
	/*! [in,out] Port on which the server listens for incoming IPv6
	 * connections. */
	uint16_t *listen_port6)
{
	int ret_code;
	int count;
	int max_count = 10000;
	MiniServerSockArray *miniSocket;
	ThreadPoolJob job;

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

	switch (gMServState) {
	case MSERV_IDLE:
		break;
	default:
		/* miniserver running. */
		return UPNP_E_INTERNAL_ERROR;
	}
	miniSocket = (MiniServerSockArray *)malloc(
		sizeof (MiniServerSockArray));
	if (!miniSocket) {
		return UPNP_E_OUTOF_MEMORY;
	}
	InitMiniServerSockArray(miniSocket);
#ifdef INTERNAL_WEB_SERVER
	/* V4 and V6 http listeners. */
	ret_code = get_miniserver_sockets(
		miniSocket, *listen_port4, *listen_port6);
	if (ret_code != UPNP_E_SUCCESS) {
		free(miniSocket);
		return ret_code;
	}
#endif
	/* Stop socket (To end miniserver processing). */
	ret_code = get_miniserver_stopsock(miniSocket);
	if (ret_code != UPNP_E_SUCCESS) {
		sock_close(miniSocket->miniServerSock4);
		sock_close(miniSocket->miniServerSock6);
		free(miniSocket);
		return ret_code;
	}
	/* SSDP socket for discovery/advertising. */
	ret_code = get_ssdp_sockets(miniSocket);
	if (ret_code != UPNP_E_SUCCESS) {
		sock_close(miniSocket->miniServerSock4);
		sock_close(miniSocket->miniServerSock6);
		sock_close(miniSocket->miniServerStopSock);
		free(miniSocket);
		return ret_code;
	}
	TPJobInit(&job, (start_routine)RunMiniServer, (void *)miniSocket);
	TPJobSetPriority(&job, MED_PRIORITY);
	TPJobSetFreeFunction(&job, (free_routine)free);
	ret_code = ThreadPoolAddPersistent(&gMiniServerThreadPool, &job, NULL);
	if (ret_code < 0) {
		sock_close(miniSocket->miniServerSock4);
		sock_close(miniSocket->miniServerSock6);
		sock_close(miniSocket->miniServerStopSock);
		sock_close(miniSocket->ssdpSock4);
		sock_close(miniSocket->ssdpSock6);
		sock_close(miniSocket->ssdpSock6UlaGua);
#ifdef INCLUDE_CLIENT_APIS
		sock_close(miniSocket->ssdpReqSock4);
		sock_close(miniSocket->ssdpReqSock6);
#endif /* INCLUDE_CLIENT_APIS */
		return UPNP_E_OUTOF_MEMORY;
	}
	/* Wait for miniserver to start. */
	count = 0;
	while (gMServState != (MiniServerState)MSERV_RUNNING && count < max_count) {
		/* 0.05s */
		usleep(50u * 1000u);
		count++;
	}
	if (count >= max_count) {
		/* Took it too long to start that thread. */
		sock_close(miniSocket->miniServerSock4);
		sock_close(miniSocket->miniServerSock6);
		sock_close(miniSocket->miniServerStopSock);
		sock_close(miniSocket->ssdpSock4);
		sock_close(miniSocket->ssdpSock6);
		sock_close(miniSocket->ssdpSock6UlaGua);
#ifdef INCLUDE_CLIENT_APIS
		sock_close(miniSocket->ssdpReqSock4);
		sock_close(miniSocket->ssdpReqSock6);
#endif /* INCLUDE_CLIENT_APIS */
		return UPNP_E_INTERNAL_ERROR;
	}
#ifdef INTERNAL_WEB_SERVER
	*listen_port4 = miniSocket->miniServerPort4;
	*listen_port6 = miniSocket->miniServerPort6;
#endif

	return UPNP_E_SUCCESS;
}
예제 #3
0
/************************************************************************
 * Function: StartMiniServer
 *
 * Parameters :
 *	unsigned short listen_port - Port on which the server listens for 
 *		incoming connections
 *
 * Description:
 * 	Initialize the sockets functionality for the 
 *	Miniserver. Initialize a thread pool job to run the MiniServer
 *	and the job to the thread pool. If listen port is 0, port is 
 *	dynamically picked
 *
 *	Use timer mechanism to start the MiniServer, failure to meet the 
 *	allowed delay aborts the attempt to launch the MiniServer.
 *
 * Return: int
 *	Actual port socket is bound to - On Success
 *	A negative number DLNA_E_XXX - On Error
 ************************************************************************/
int
StartMiniServer( unsigned short listen_port )
{
    int success;
    int count;
    int max_count = 10000;

    MiniServerSockArray *miniSocket;
    ThreadPoolJob job;

    if( gMServState != MSERV_IDLE ) {
        return DLNA_E_INTERNAL_ERROR;   // miniserver running
    }

    miniSocket =
        ( MiniServerSockArray * ) malloc( sizeof( MiniServerSockArray ) );
    if( miniSocket == NULL )
        return DLNA_E_OUTOF_MEMORY;

    if( ( success = get_miniserver_sockets( miniSocket, listen_port ) )
        != DLNA_E_SUCCESS ) {
        free( miniSocket );
        return success;
    }

    if( ( success = get_ssdp_sockets( miniSocket ) ) != DLNA_E_SUCCESS ) {
        shutdown( miniSocket->miniServerSock, SD_BOTH );
        dlnaCloseSocket( miniSocket->miniServerSock );
        shutdown( miniSocket->miniServerStopSock, SD_BOTH );
        dlnaCloseSocket( miniSocket->miniServerStopSock );
        free( miniSocket );

        return success;
    }

    TPJobInit( &job, ( start_routine ) RunMiniServer,
               ( void * )miniSocket );
    TPJobSetPriority( &job, MED_PRIORITY );

    TPJobSetFreeFunction( &job, ( free_routine ) free );

    success = ThreadPoolAddPersistent( &gMiniServerThreadPool, &job, NULL );

    if( success < 0 ) {
        shutdown( miniSocket->miniServerSock, SD_BOTH );
        dlnaCloseSocket( miniSocket->miniServerSock );
        shutdown( miniSocket->miniServerStopSock, SD_BOTH );
        dlnaCloseSocket( miniSocket->miniServerStopSock );
        shutdown( miniSocket->ssdpSock, SD_BOTH );
        dlnaCloseSocket( miniSocket->ssdpSock );
#ifdef INCLUDE_CLIENT_APIS
        shutdown( miniSocket->ssdpReqSock, SD_BOTH );
        dlnaCloseSocket( miniSocket->ssdpReqSock );
#endif

        return DLNA_E_OUTOF_MEMORY;
    }
    // wait for miniserver to start
    count = 0;
    while( gMServState != MSERV_RUNNING && count < max_count ) {
        usleep( 50 * 1000 );    // 0.05s
        count++;
    }

    // taking too long to start that thread
    if( count >= max_count ) {
        shutdown( miniSocket->miniServerSock, SD_BOTH );
        dlnaCloseSocket( miniSocket->miniServerSock );
        shutdown( miniSocket->miniServerStopSock, SD_BOTH );
        dlnaCloseSocket( miniSocket->miniServerStopSock );
        shutdown( miniSocket->ssdpSock, SD_BOTH );
        dlnaCloseSocket( miniSocket->ssdpSock );
#ifdef INCLUDE_CLIENT_APIS
        shutdown( miniSocket->ssdpReqSock, SD_BOTH );
        dlnaCloseSocket( miniSocket->ssdpReqSock );
#endif

        return DLNA_E_INTERNAL_ERROR;
    }

    return miniSocket->miniServerPort;
}