int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_socket_type_t type, tsk_bool_t take_ownership, tsk_bool_t isClient)
{
	tnet_transport_t *transport = (tnet_transport_t*)handle;
	transport_context_t* context;
	int ret = -1;
    
	if (!transport) {
		TSK_DEBUG_ERROR("Invalid server handle.");
		return ret;
	}
	
	if (!(context = (transport_context_t*)transport->context)) {
		TSK_DEBUG_ERROR("Invalid context.");
		return -2;
	}
    
	if (TNET_SOCKET_TYPE_IS_TLS(type)) {
		transport->tls.have_tls = 1;
	}
	
	if ((ret = addSocket(fd, type, transport, take_ownership, isClient))) {
		TSK_DEBUG_ERROR("Failed to add new Socket.");
		return ret;
	}
    
	if (context->cf_run_loop) {
		// Signal the run-loop
        CFRunLoopWakeUp(context->cf_run_loop);
        return 0;
	} else {
		TSK_DEBUG_WARN("run_loop not initialized yet.");
		return 0; //Will be taken when mainthead start
	}
}
/*
 * Set the given sockets to the socket list to be listen on
 */
void MultipleTCPSocketsListener::addSockets(vector<TCPSocket*> socketVec)
{
	// set the given sockets as the socket list to selct from
	for (unsigned int i = 0; i < socketVec.size(); i++)
	{
		addSocket(socketVec[i]);
	}
}
int tnet_transport_prepare(tnet_transport_t *transport)
{
    int ret = -1;
    transport_context_t *context;

    if (!transport || !transport->context) {
        TSK_DEBUG_ERROR("Invalid parameter.");
        return -1;
    }
    else {
        context = transport->context;
    }

    if (transport->prepared) {
        TSK_DEBUG_ERROR("Transport already prepared.");
        return -2;
    }

    /* Prepare master */
    if (!transport->master) {
        if ((transport->master = tnet_socket_create(transport->local_host, transport->req_local_port, transport->type))) {
            tsk_strupdate(&transport->local_ip, transport->master->ip);
            transport->bind_local_port = transport->master->port;
        }
        else {
            TSK_DEBUG_ERROR("Failed to create master socket");
            return -3;
        }
    }

    /* Start listening */
    if (TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)) {
        if ((ret = tnet_sockfd_listen(transport->master->fd, WSA_MAXIMUM_WAIT_EVENTS))) {
            TNET_PRINT_LAST_ERROR("listen have failed.");
            goto bail;
        }
    }

    /* Add the master socket to the context. */
    // don't take ownership: will be closed by the dctor() when refCount==0
    // otherwise will be closed twice: dctor() and removeSocket()
    if ((ret = addSocket(transport->master->fd, transport->master->type, transport, tsk_false, tsk_false, tsk_null))) {
        TSK_DEBUG_ERROR("Failed to add master socket");
        goto bail;
    }

    /* set events on master socket */
    if ((ret = WSAEventSelect(transport->master->fd, context->events[context->count - 1], FD_ALL_EVENTS) == SOCKET_ERROR)) {
        TNET_PRINT_LAST_ERROR("WSAEventSelect have failed.");
        goto bail;
    }

    transport->prepared = tsk_true;

bail:
    return ret;
}
PollSet::PollSet()
: sockets_changed_(false)
{
	if ( create_signal_pair(signal_pipe_) != 0 ) {
        ROS_FATAL("create_signal_pair() failed");
        ROS_BREAK();
	}
  addSocket(signal_pipe_[0], boost::bind(&PollSet::onLocalPipeEvents, this, _1));
  addEvents(signal_pipe_[0], POLLIN);
}
Example #5
0
bool ServerSocketManager::start()
{
	if (!BaseSocketManager::init())
        return false;

	GameServerListenSocket* socket = new GameServerListenSocket(3709);
	addSocket(socket);

	return true;
}
CCUDPSocket* CCUDPSocketHub::createSocket(const string& hostname, int port, int tag, int blockSec) {
	CCUDPSocket* s = CCUDPSocket::create(hostname, port, tag, blockSec);
	if (s && addSocket(s)) {
		CCUDPSocketListener* l = getListener(tag);
		if(l) {
			l->onUDPSocketBound(tag);
		}
	}
	
	return s;
}
CCTCPSocket* CCTCPSocketHub::createSocket(const string& hostname, int port, int tag, int blockSec, bool keepAlive) {
	CCTCPSocket* s = CCTCPSocket::create(hostname, port, tag, blockSec, keepAlive);
	if (s && addSocket(s) && s->isConnected()) {
		CCTCPSocketListener* l = getListener(tag);
		if(l) {
			l->onTCPSocketConnected(tag);
		}
	}
	
	return s;
}
Example #8
0
bool SkpLocalManageRoute::onRouteChan(void *head, int headSize, void *data, int dataSize)
{
    SKP_UNUSED(head);
    SKP_UNUSED(headSize);
    uint64 serverID = m_routeServerID;
    printf("send to serverID = %lld \n", serverID);
    if(sendSocket(serverID, data, dataSize)) {
        return skp_true;
    }

    printf("connect to serverID = %lld \n", serverID);
    SkpLocalSocketTcp *localSocketTcp = new SkpLocalSocketTcp(this);
    localSocketTcp->addDel(std::bind(&SkpLocalManageRoute::delSocket, this, std::placeholders::_1, std::placeholders::_2));
    int res = localSocketTcp->connect(m_routeServerIP.c_str(), m_routeServerID);

    if(res != Skp::Connect_Error_Success) {
        printf("skp_send_route_conn connect error \n");
        skp_delete(localSocketTcp);
        return skp_false;
    }

    localSocketTcp->m_isConn = skp_true;
    localSocketTcp->m_isOwner = skp_true;

    localSocketTcp->start();
    uchar connTypeLocal = ConnTypeLocal;
    uchar connTypeRemote = ConnTypeRoute;
    SkpPakegeConnHead(&localSocketTcp->m_connHead, 1, connTypeLocal, 0, m_serverID, serverID);

    bool isRes = localSocketTcp->appendWriteChan(&localSocketTcp->m_connHead, localSocketTcp->m_connHead.headSize);
    if(!isRes) {
        printf("skp_send_route_conn push 222 error \n");
        skp_delete(localSocketTcp);
        return isRes;
    } else {
        //printf("skp_send_route_conn ok \n");
    }

    localSocketTcp->m_connHead.connType = connTypeRemote;

    isRes = localSocketTcp->appendWriteChan(data, dataSize);
    if(!isRes) {
        //printf("skp_send_route_conn push 333 error \n");
        skp_delete(localSocketTcp);
        return isRes;
    }

    addSocket(serverID, localSocketTcp);

    return skp_true;
}
int tnet_transport_prepare(tnet_transport_t *transport)
{
	int ret = -1;
	transport_context_t *context;
	
	if(!transport || !transport->context){
		TSK_DEBUG_ERROR("Invalid parameter.");
		return -1;
	}
	else{
		context = transport->context;
	}
	
	if(transport->prepared){
		TSK_DEBUG_ERROR("Transport already prepared.");
		return -2;
	}
	
	/* Start listening */
	if(TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)){
		if((ret = tnet_sockfd_listen(transport->master->fd, WSA_MAXIMUM_WAIT_EVENTS))){
			TNET_PRINT_LAST_ERROR("listen have failed.");
			goto bail;
		}
	}
	
	/* Add the master socket to the context. */
	if((ret = addSocket(transport->master->fd, transport->master->type, transport, tsk_true, tsk_false))){
		TSK_DEBUG_ERROR("Failed to add master socket");
		goto bail;
	}
	
	/* set events on master socket */
	if((ret = WSAEventSelect(transport->master->fd, context->events[context->count - 1], TNET_SOCKET_TYPE_IS_DGRAM(transport->master->type) ? FD_READ : FD_ALL_EVENTS/*FD_ACCEPT | FD_READ | FD_CONNECT | FD_CLOSE*/) == SOCKET_ERROR)){
		TNET_PRINT_LAST_ERROR("WSAEventSelect have failed.");
		goto bail;
	}
	
	transport->prepared = tsk_true;
	
bail:
	return ret;
}
int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_socket_type_t type, tsk_bool_t take_ownership, tsk_bool_t isClient, tnet_tls_socket_handle_t* tlsHandle)
{
    tnet_transport_t *transport = (tnet_transport_t*)handle;
    transport_context_t* context;
    static char c = '\0';
    int ret = -1;

    if(!transport) {
        TSK_DEBUG_ERROR("Invalid server handle.");
        return ret;
    }

    if(!(context = (transport_context_t*)transport->context)) {
        TSK_DEBUG_ERROR("Invalid context.");
        return -2;
    }

    if(TNET_SOCKET_TYPE_IS_TLS(type) || TNET_SOCKET_TYPE_IS_WSS(type)) {
        transport->tls.enabled = 1;
    }

    if((ret = addSocket(fd, type, transport, take_ownership, isClient, tlsHandle))) {
        TSK_DEBUG_ERROR("Failed to add new Socket.");
        return ret;
    }

    // signal
    if(context->pipeW && (TSK_RUNNABLE(transport)->running || TSK_RUNNABLE(transport)->started)) {
        if((ret = write(context->pipeW, &c, 1)) > 0) {
            TSK_DEBUG_INFO("Socket added (external call) %d", fd);
            return 0;
        }
        else {
            TSK_DEBUG_ERROR("Failed to add new Socket.");
            return ret;
        }
    }
    else {
        TSK_DEBUG_INFO("pipeW (write site) not initialized yet.");
        return 0; //Will be taken when mainthead start
    }
}
/*
* Add new socket to the watcher.
*/
int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_socket_type_t type, tsk_bool_t take_ownership, tsk_bool_t isClient, tnet_tls_socket_handle_t* tlsHandle)
{
    tnet_transport_t *transport = (tnet_transport_t*)handle;
    transport_context_t* context;
    int ret = -1;

    if (!transport) {
        TSK_DEBUG_ERROR("Invalid server handle.");
        return ret;
    }

    if (!(context = (transport_context_t*)transport->context)) {
        TSK_DEBUG_ERROR("Invalid context.");
        return -2;
    }

    if (TNET_SOCKET_TYPE_IS_TLS(type) || TNET_SOCKET_TYPE_IS_WSS(type)) {
        transport->tls.enabled = tsk_true;
    }

    addSocket(fd, type, transport, take_ownership, isClient, tlsHandle);

    if (WSAEventSelect(fd, context->events[context->count - 1], FD_ALL_EVENTS) == SOCKET_ERROR) {
        removeSocket((int)(context->count - 1), context);
        TNET_PRINT_LAST_ERROR("WSAEventSelect have failed.");
        return -1;
    }

    /* Signal if transport is running */
    if (TSK_RUNNABLE(transport)->running || TSK_RUNNABLE(transport)->started) {
        if (WSASetEvent(context->events[0])) {
            TSK_DEBUG_INFO("New socket added to the network transport.");
            return 0;
        }
        TSK_DEBUG_ERROR("Transport not started yet");
        return -1;
    }

    TSK_DEBUG_INFO("Adding socket delayed");
    return 0;
}
int tnet_transport_prepare(tnet_transport_t *transport)
{
	int ret = -1;
	transport_context_t *context;
	
	if (!transport || !transport->context) {
		TSK_DEBUG_ERROR("Invalid parameter.");
		return -1;
	}
	else{
		context = transport->context;
	}
	
	if (transport->prepared) {
		TSK_DEBUG_ERROR("Transport already prepared.");
		return -2;
	}
	
	/* Start listening */
	if (TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)) {
		if ((ret = tnet_sockfd_listen(transport->master->fd, TNET_MAX_FDS))) {
			TNET_PRINT_LAST_ERROR("listen have failed.");
			goto bail;
		}
	}
	
	/* Add the master socket to the context. */
	if ((ret = addSocket(transport->master->fd, transport->master->type, transport, tsk_true, tsk_false))) {
		TSK_DEBUG_ERROR("Failed to add master socket");
		goto bail;
	}
	
	transport->prepared = tsk_true;
	
bail:
	return ret;
}
/* 
* Add new socket to the watcher.
*/
int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_socket_type_t type, tsk_bool_t take_ownership, tsk_bool_t isClient)
{
	tnet_transport_t *transport = (tnet_transport_t*)handle;
	transport_context_t* context;
	int ret = -1;

	if(!transport){
		TSK_DEBUG_ERROR("Invalid server handle.");
		return ret;
	}

	if(!(context = (transport_context_t*)transport->context)){
		TSK_DEBUG_ERROR("Invalid context.");
		return -2;
	}

	if(TNET_SOCKET_TYPE_IS_TLS(type)){
		transport->tls.have_tls = 1;
	}

	addSocket(fd, type, transport, take_ownership, isClient);
	if(WSAEventSelect(fd, context->events[context->count - 1], FD_ALL_EVENTS) == SOCKET_ERROR){
		removeSocket((context->count - 1), context);
		TNET_PRINT_LAST_ERROR("WSAEventSelect have failed.");
		return -1;
	}

	/* Signal */
	if(WSASetEvent(context->events[0])){
		TSK_DEBUG_INFO("New socket added to the network transport.");
		return 0;
	}

	// ...
	
	return -1;
}
Example #14
0
/**
 * @brief Adds remote peer or finds via DNS
 * 
 * @param address Address to add
 * @param port Port to connect to
 * @param outport Port to connect on
 * @return 0 on fail, 1 on success, 2 if already bound
 */
int Peer::AddRemotePeer(const std::string address, const int port, const int outport)
{
	IPaddress ip;
	ip.port = port;
	
	Print("resolving host...\n");
	if (SDLNet_ResolveHost(&ip, address.c_str(), 0)==-1)
	{
		Print("Some DNS requests require more then one request before you will get a response!\n");
		return 0;
	}
	Print("found dns match: %s\n", getIP(ip.host));
	Print("checking for avaliable sockets...\n");
	//Do we have any sockets?
	if (sockets.size()) 
	{
		//if no, add one
		if (!addSocket(outport))
		{
			//if we failed to add one, return
			return 0;
		}
	}

	// try and see if this peer already has a socket / channel bound
	Print("crosschecking with current peers...\n");
	auto gp = GetRemotePeer(&ip);
	if (std::get<0>(gp)!=-1 && std::get<1>(gp)!=-1)
	{
		return 2; // if already bound then return 2
	}

	Print("finding an empty socket channel...\n");
	//TODO: write a function that finds an empty socket/channel maybe
	// find an empty channel to bind the peer to
	for (UDPsocket &sock : sockets)
	{
		if (outport) // if we want a specific outport
		{
			// and the socket we are checking is not our desired port
			Uint16 port = SDLNet_UDP_GetPeerAddress(sock,-1)->port;
			if (SDLNet_Read16(&port) != outport)
				continue; // skip this iteration
		}

		for ( int i = 0; i < (SDLNET_MAX_UDPADDRESSES-1); i++)
		{
			IPaddress *peer = SDLNet_UDP_GetPeerAddress(sock,i);
			if (!peer)
			{
				Print("Found an empty sock / channel\n");
				int channel = SDLNet_UDP_Bind(sock, i, &ip);
				if (channel == -1)
				{
					Print("SDLNet_UDP_Bind: %s\n", SDLNet_GetError());
					return 0; // Failed to bind
				}
				else
				{
					Print("BOUND\n");
					return 1; // Bound!
				}
			}
		}
	}

	Print("none found, adding a new socket and trying again...\n");
	// if no empty channel found, add socket and try again

	if (!addSocket(outport))
	{
		//if we failed to add one, return
		return 0;
	}

	for (UDPsocket &sock : sockets)
	{
		if (outport) // if we want a specific outport
		{
			// and the socket we are checking is not our desired port
			Uint16 port = SDLNet_UDP_GetPeerAddress(sock,-1)->port;
			if (SDLNet_Read16(&port) != outport){
				continue; // skip this iteration
			}
		}

		for ( int i = 0; i < (SDLNET_MAX_UDPADDRESSES-1); i++)
		{
			IPaddress *peer = SDLNet_UDP_GetPeerAddress(sock, i);
			if (!peer)
			{
				Print("Found an empty sock / channel\n");
				
				int channel = SDLNet_UDP_Bind(sock, i, &ip);
				if (channel == -1)
				{
					Print("SDLNet_UDP_Bind: %s\n", SDLNet_GetError());
					return 0; // Failed to bind
				}
				else
				{
					Print("BOUND\n");
					return 1; // Bound!
				}
			}
		}
	}
	Print("did not bind.\n");
	return 0;
	//for (IPaddress & ip : SDLNet_UDP_GetPeerAddress(,-1))
}
int tnet_transport_prepare(tnet_transport_t *transport)
{
    int ret = -1;
    transport_context_t *context;
    tnet_fd_t pipes[2];

    TSK_DEBUG_INFO("tnet_transport_prepare()");

    if(!transport || !transport->context) {
        TSK_DEBUG_ERROR("Invalid parameter.");
        return -1;
    }
    else {
        context = transport->context;
    }

    if(transport->prepared) {
        TSK_DEBUG_ERROR("Transport already prepared.");
        return -2;
    }

    /* Prepare master */
    if(!transport->master) {
        if((transport->master = tnet_socket_create(transport->local_host, transport->req_local_port, transport->type))) {
            tsk_strupdate(&transport->local_ip, transport->master->ip);
            transport->bind_local_port = transport->master->port;
        }
        else {
            TSK_DEBUG_ERROR("Failed to create master socket");
            return -3;
        }
    }

    /* Start listening */
    if(TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)) {
        if((ret = tnet_sockfd_listen(transport->master->fd, TNET_MAX_FDS))) {
            TNET_PRINT_LAST_ERROR("listen have failed.");
            goto bail;
        }
    }

    /* Create and add pipes to the fd_set */
    if((ret = pipe(pipes))) {
        TNET_PRINT_LAST_ERROR("Failed to create new pipes.");
        goto bail;
    }

    /* set both R and W sides */
    context->pipeR = pipes[0];
    context->pipeW = pipes[1];

    /* add R side */
    TSK_DEBUG_INFO("pipeR fd=%d, pipeW=%d", context->pipeR, context->pipeW);
    if((ret = addSocket(context->pipeR, transport->master->type, transport, tsk_true, tsk_false, tsk_null))) {
        goto bail;
    }

    /* Add the master socket to the context. */
    TSK_DEBUG_INFO("master fd=%d", transport->master->fd);
    // don't take ownership: will be closed by the dctor() when refCount==0
    // otherwise will be closed twice: dctor() and removeSocket()
    if((ret = addSocket(transport->master->fd, transport->master->type, transport, tsk_false, tsk_false, tsk_null))) {
        TSK_DEBUG_ERROR("Failed to add master socket");
        goto bail;
    }

    transport->prepared = tsk_true;

bail:
    return ret;
}
/*=== Main thread */
void* TSK_STDCALL tnet_transport_mainthread(void *param)
{
    tnet_transport_t *transport = (tnet_transport_t*)param;
    transport_context_t *context = (transport_context_t*)transport->context;
    DWORD evt;
    WSANETWORKEVENTS networkEvents;
    DWORD flags = 0;
    int ret;

    struct sockaddr_storage remote_addr = { 0 };
    WSAEVENT active_event;
    transport_socket_xt* active_socket;
    int index;

    TSK_DEBUG_INFO("Starting [%s] server with IP {%s} on port {%d} with type {%d}...", transport->description, transport->master->ip, transport->master->port, transport->master->type);

    while (TSK_RUNNABLE(transport)->running || TSK_RUNNABLE(transport)->started) {
        /* Wait for multiple events */
        if ((evt = WSAWaitForMultipleEvents((DWORD)context->count, context->events, FALSE, WSA_INFINITE, FALSE)) == WSA_WAIT_FAILED) {
            TNET_PRINT_LAST_ERROR("WSAWaitForMultipleEvents have failed.");
            goto bail;
        }

        if (!TSK_RUNNABLE(transport)->running && !TSK_RUNNABLE(transport)->started) {
            goto bail;
        }

        /* lock context */
        tsk_safeobj_lock(context);

        /* Get active event and socket */
        index = (evt - WSA_WAIT_EVENT_0);
        active_event = context->events[index];
        if (!(active_socket = context->sockets[index])) {
            goto done;
        }

        /* Get the network events flags */
        if (WSAEnumNetworkEvents(active_socket->fd, active_event, &networkEvents) == SOCKET_ERROR) {
            TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, active_socket->fd);
            TNET_PRINT_LAST_ERROR("WSAEnumNetworkEvents have failed.");

            tsk_safeobj_unlock(context);
            goto bail;
        }

        /*================== FD_ACCEPT ==================*/
        if (networkEvents.lNetworkEvents & FD_ACCEPT) {
            tnet_fd_t fd;

            TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_ACCEPT", transport->description);

            if (networkEvents.iErrorCode[FD_ACCEPT_BIT]) {
                TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, active_socket->fd);
                TNET_PRINT_LAST_ERROR("ACCEPT FAILED.");
                goto done;
            }

            /* Accept the connection */
            if ((fd = (tnet_fd_t)WSAAccept(active_socket->fd, NULL, NULL, AcceptCondFunc, (DWORD_PTR)context)) != INVALID_SOCKET) {
                /* Add the new fd to the server context */
                addSocket(fd, transport->master->type, transport, tsk_true, tsk_false, tsk_null);
                if (active_socket->tlshandle) {
                    transport_socket_xt* tls_socket;
                    if ((tls_socket = getSocket(context, fd))) {
                        if (tnet_tls_socket_accept(tls_socket->tlshandle)) {
                            tnet_transport_remove_socket(transport, &fd);
                            TNET_PRINT_LAST_ERROR("SSL_accept() failed");
                            goto done;
                        }
                    }
                }
                if (WSAEventSelect(fd, context->events[context->count - 1], FD_READ | FD_WRITE | FD_CLOSE) == SOCKET_ERROR) {
                    tnet_transport_remove_socket(transport, &fd);
                    TNET_PRINT_LAST_ERROR("WSAEventSelect() have failed.");
                    goto done;
                }
                TSK_RUNNABLE_ENQUEUE(transport, event_accepted, transport->callback_data, fd);
            }
            else {
                TNET_PRINT_LAST_ERROR("ACCEPT FAILED.");
                goto done;
            }




        }

        /*================== FD_CONNECT ==================*/
        if (networkEvents.lNetworkEvents & FD_CONNECT) {
            TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_CONNECT", transport->description);

            if (networkEvents.iErrorCode[FD_CONNECT_BIT]) {
                tnet_fd_t fd = active_socket->fd;
                TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, fd);
                tnet_transport_remove_socket(transport, &fd);
                TNET_PRINT_LAST_ERROR("CONNECT FAILED.");
                goto done;
            }
            else {
                TSK_RUNNABLE_ENQUEUE(transport, event_connected, transport->callback_data, active_socket->fd);
                active_socket->connected = 1;
            }
        }


        /*================== FD_READ ==================*/
        if (networkEvents.lNetworkEvents & FD_READ) {
            DWORD readCount = 0;
            WSABUF wsaBuffer;

            /* TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_READ", transport->description); */

            /* check whether the socket is paused or not */
            if (active_socket->paused) {
                TSK_DEBUG_INFO("Socket is paused");
                goto FD_READ_DONE;
            }

            if (networkEvents.iErrorCode[FD_READ_BIT]) {
                TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, active_socket->fd);
                TNET_PRINT_LAST_ERROR("READ FAILED.");
                goto done;
            }

            /* Retrieve the amount of pending data */
            if (tnet_ioctlt(active_socket->fd, FIONREAD, &(wsaBuffer.len)) < 0) {
                TNET_PRINT_LAST_ERROR("IOCTLT FAILED.");
                goto done;
            }

            if (!wsaBuffer.len) {
                goto done;
            }

            /* Alloc data */
            if (!(wsaBuffer.buf = tsk_calloc(wsaBuffer.len, sizeof(uint8_t)))) {
                goto done;
            }

            /* Retrieve the remote address */
            if (TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)) {
                ret = tnet_getpeername(active_socket->fd, &remote_addr);
            }

            /* Receive the waiting data. */
            if (active_socket->tlshandle) {
                int isEncrypted;
                tsk_size_t len = wsaBuffer.len;
                if (!(ret = tnet_tls_socket_recv(active_socket->tlshandle, &wsaBuffer.buf, &len, &isEncrypted))) {
                    if (isEncrypted) {
                        TSK_FREE(wsaBuffer.buf);
                        goto done;
                    }
                    wsaBuffer.len = (ULONG)len;
                }
            }
            else {
                if (TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)) {
                    ret = WSARecv(active_socket->fd, &wsaBuffer, 1, &readCount, &flags, 0, 0);
                }
                else {
                    int len = sizeof(remote_addr);
                    ret = WSARecvFrom(active_socket->fd, &wsaBuffer, 1, &readCount, &flags,
                                      (struct sockaddr*)&remote_addr, &len, 0, 0);
                }
                if (readCount < wsaBuffer.len) {
                    wsaBuffer.len = readCount;
                    /* wsaBuffer.buf = tsk_realloc(wsaBuffer.buf, readCount); */
                }
            }

            if (ret) {
                ret = WSAGetLastError();
                if (ret == WSAEWOULDBLOCK) {
                    // Doesn't (always) mean congestion but... another thread is also poll()ing the FD. For example, when TURN session has a reference to the fd.
                    TSK_DEBUG_WARN("WSAEWOULDBLOCK error for READ SSESSION");
                }
                else if (ret == WSAECONNRESET && TNET_SOCKET_TYPE_IS_DGRAM(transport->master->type)) {
                    /* For DGRAM ==> The sent packet gernerated "ICMP Destination/Port unreachable" result. */
                    TSK_FREE(wsaBuffer.buf);
                    goto done; // ignore and retry.
                }
                else {
                    TSK_FREE(wsaBuffer.buf);

                    removeSocket(index, context);
                    TNET_PRINT_LAST_ERROR("WSARecv have failed.");
                    goto done;
                }
            }
            else {
                tnet_transport_event_t* e = tnet_transport_event_create(event_data, transport->callback_data, active_socket->fd);
                transport->bytes_in += wsaBuffer.len;
                e->data = wsaBuffer.buf;
                e->size = wsaBuffer.len;
                e->remote_addr = remote_addr;

                TSK_RUNNABLE_ENQUEUE_OBJECT_SAFE(TSK_RUNNABLE(transport), e);
            }
FD_READ_DONE:
            ;
        }




        /*================== FD_WRITE ==================*/
        if (networkEvents.lNetworkEvents & FD_WRITE) {
            TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_WRITE", transport->description);

            if (networkEvents.iErrorCode[FD_WRITE_BIT]) {
                TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, active_socket->fd);
                TNET_PRINT_LAST_ERROR("WRITE FAILED.");
                goto done;
            }
        }



        /*================== FD_CLOSE ==================*/
        if (networkEvents.lNetworkEvents & FD_CLOSE) {
            TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_CLOSE", transport->description);

            TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, active_socket->fd);
            removeSocket(index, context);
        }

        /*	http://msdn.microsoft.com/en-us/library/ms741690(VS.85).aspx

        	The proper way to reset the state of an event object used with the WSAEventSelect function
        	is to pass the handle of the event object to the WSAEnumNetworkEvents function in the hEventObject parameter.
        	This will reset the event object and adjust the status of active FD events on the socket in an atomic fashion.
        	*/
        /* WSAResetEvent(active_event); <== DO NOT USE (see above) */

done:
        /* unlock context */
        tsk_safeobj_unlock(context);
    } /* while(transport->running) */


bail:

    TSK_DEBUG_INFO("Stopped [%s] server with IP {%s} on port {%d} with type {%d}...", transport->description, transport->master->ip, transport->master->port, transport->master->type);
    return tsk_null;
}
Example #17
0
void Epoll::wait_once()
{
		int ret;
		pthread_rwlock_rdlock(&rwlock);
		int socketNum=fdNum;
		pthread_rwlock_unlock(&rwlock);
		struct epoll_event events[socketNum];
		ret=epoll_wait(epollFd,events,socketNum,-1);
		if(ret==-1)
		{
				if(errno==EINTR)
				{
						errno=0;
						return;
				}
				else
						throw Exception(ERR_SHIT,"Epoll_wait()调用失败",errno);
		}
		else if(ret>0)
		{
				for(int times=0;times<ret;times++)
				{
						int fd=events[times].data.fd;
						Socket &socket=socketManager.find(fd);
						if(events[times].events & EPOLLRDHUP)//对方关闭了连接
						{
								//从EPOLL移除Socket
								rmSocket(fd);
								//关闭Socket
								socket.close();
								//从Socket管理器中删除
								socketManager.rmSocket(socket);
						}
						else if(events[times].events==EPOLLIN)//有消息可读
						{
								if(fd==ListenedFd)//监听Socket有消息到达
								{
										int peerfd=socket.accept(NULL,0);	//Accept一个新连接
										Socket peer(peerfd);
										peer.setNonBlock();
										socketManager.addSocket(peer);		//添加到Socket管理器
										addSocket(peerfd);					//添加到Epoll
								}
								else if(fd==RdPipe)
								{
										//向前台进程返回信息
										uint8 req;
										read(RdPipe,&req,sizeof(req));
										if(req==BALANCE_LOCAL)
										{
												//返回本地负载信息
                                                uint64 num=socketManager.getNum();
                                                uint64 max=socketManager.getMax();
												
												write(WrPipe,&num,sizeof(num));//发送当前负载数
												write(WrPipe,&max,sizeof(max));//发送上限
										}
								}
								else//有TCP消息到达
								{
										try{
										if(socket.isLocked())
												continue;
										socket.dispose();//将消息放入消息队列中
										threadPool.addWork();
										}
										catch(Exception &error)
										{
												error.exit();
												continue;
										}
								}
						}
				}
		}
}
/*=== Main thread */
void *tnet_transport_mainthread(void *param)
{
    tnet_transport_t *transport = param;
    transport_context_t *context = transport->context;
    int ret, status;
    tsk_size_t i;
    tsk_bool_t is_stream;
    tnet_fd_t fd;

    struct sockaddr_storage remote_addr = {0};
    transport_socket_xt* active_socket;

    /* check whether the transport is already prepared */
    if(!transport->prepared) {
        TSK_DEBUG_ERROR("Transport must be prepared before strating.");
        goto bail;
    }

    is_stream = TNET_SOCKET_TYPE_IS_STREAM(transport->master->type);

    TSK_DEBUG_INFO("Starting [%s] server with IP {%s} on port {%d} using master fd {%d} with type {%d} with max_fds {%lu}...",
                   transport->description,
                   transport->master->ip,
                   transport->master->port,
                   transport->master->fd,
                   transport->master->type,
                   sizeof(context->ufds)/sizeof(context->ufds[0]));

    while(TSK_RUNNABLE(transport)->running || TSK_RUNNABLE(transport)->started) {
        context->polling = tsk_true;
        ret = tnet_poll(context->ufds, context->count, -1);
        context->polling = tsk_false;
        if(ret < 0) {
            TNET_PRINT_LAST_ERROR("poll() have failed.");
            goto bail;
        }

        if(!TSK_RUNNABLE(transport)->running && !TSK_RUNNABLE(transport)->started) {
            TSK_DEBUG_INFO("Stopping [%s] server with IP {%s} on port {%d} with type {%d}...", transport->description, transport->master->ip, transport->master->port, transport->master->type);
            goto bail;
        }

        /* lock context */
        tsk_safeobj_lock(context);

        /* == == */
        for(i=0; i<context->count; i++) {
            if(!context->ufds[i].revents) {
                continue;
            }

            // TSK_DEBUG_INFO("REVENTS(i=%d) = %d", i, context->ufds[i].revents);

            if(context->ufds[i].fd == context->pipeR) {
                TSK_DEBUG_INFO("PipeR event = %d", context->ufds[i].revents);
                if(context->ufds[i].revents & TNET_POLLIN) {
                    static char __buffer[1024];
                    if(read(context->pipeR, __buffer, sizeof(__buffer)) < 0) {
                        TNET_PRINT_LAST_ERROR("Failed to read from the Pipe");
                    }
                }
                else if(context->ufds[i].revents & TNET_POLLHUP) {
                    TNET_PRINT_LAST_ERROR("Pipe Error");
                    goto bail;
                }
                context->ufds[i].revents = 0;
                continue;
            }

            /* Get active event and socket */
            active_socket = context->sockets[i];

            /*================== TNET_POLLHUP ==================*/
            if(context->ufds[i].revents & (TNET_POLLHUP)) {
                if(context->ufds[i].revents & TNET_POLLOUT) {
                    TSK_DEBUG_INFO("POLLOUT and POLLHUP are exclusive");
                }
                else {
                    fd = active_socket->fd;
                    TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLHUP(%d)", transport->description, fd);

                    tnet_transport_remove_socket(transport, &active_socket->fd);
                    TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, fd);
                    continue;
                }
            }

            /*================== TNET_POLLERR ==================*/
            if(context->ufds[i].revents & (TNET_POLLERR)) {
                fd = active_socket->fd;
                TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLERR(%d)", transport->description, fd);

                tnet_transport_remove_socket(transport, &active_socket->fd);
                TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, fd);
                continue;
            }

            /*================== TNET_POLLNVAL ==================*/
            if(context->ufds[i].revents & (TNET_POLLNVAL)) {
                fd = active_socket->fd;
                TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLNVAL(%d)", transport->description, fd);

                tnet_transport_remove_socket(transport, &active_socket->fd);
                TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, fd);
                continue;
            }

            /*================== POLLIN ==================*/
            if(context->ufds[i].revents & TNET_POLLIN) {
                tsk_size_t len = 0;
                void* buffer = tsk_null;
                tnet_transport_event_t* e;

                // TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLIN(%d)", transport->description, active_socket->fd);

                /* check whether the socket is paused or not */
                if(active_socket->paused) {
                    TSK_DEBUG_INFO("Socket is paused");
                    goto TNET_POLLIN_DONE;
                }

                /* Retrieve the amount of pending data.
                 * IMPORTANT: If you are using Symbian please update your SDK to the latest build (August 2009) to have 'FIONREAD'.
                 * This apply whatever you are using the 3rd or 5th edition.
                 * Download link: http://wiki.forum.nokia.com/index.php/Open_C/C%2B%2B_Release_History
                 */
                ret = tnet_ioctlt(active_socket->fd, FIONREAD, &len);
                if((ret < 0 || !len) && is_stream) {
                    /* It's probably an incoming connection --> try to accept() it */
                    int listening = 0, remove_socket = 0;
                    socklen_t socklen = sizeof(listening);

                    TSK_DEBUG_INFO("ioctlt(%d), len=%u returned zero or failed", active_socket->fd, (unsigned)len);

                    // check if socket is listening
                    if(getsockopt(active_socket->fd, SOL_SOCKET, SO_ACCEPTCONN, &listening, &socklen) != 0) {
#if defined(BSD) /* old FreeBSD versions (and OSX up to Lion) do not support SO_ACCEPTCONN */
                        listening = 1;
#else
                        TNET_PRINT_LAST_ERROR("getsockopt(SO_ACCEPTCONN, %d) failed\n", active_socket->fd);
                        /* not socket accepted -> no socket to remove */
                        goto TNET_POLLIN_DONE;
#endif
                    }
                    if (listening) {
                        if((fd = accept(active_socket->fd, tsk_null, tsk_null)) != TNET_INVALID_SOCKET) {
                            TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_ACCEPT(fd=%d)", transport->description, fd);
                            addSocket(fd, transport->master->type, transport, tsk_true, tsk_false, tsk_null);
                            TSK_RUNNABLE_ENQUEUE(transport, event_accepted, transport->callback_data, fd);
                            if(active_socket->tlshandle) {
                                transport_socket_xt* tls_socket;
                                if((tls_socket = getSocket(context, fd))) {
                                    if(tnet_tls_socket_accept(tls_socket->tlshandle) != 0) {
                                        TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, fd);
                                        tnet_transport_remove_socket(transport, &fd);
                                        TNET_PRINT_LAST_ERROR("SSL_accept() failed");
                                        continue;
                                    }
                                }
                            }
                        }
                        else {
                            TNET_PRINT_LAST_ERROR("accept(%d) failed", active_socket->fd);
                            remove_socket = 1;
                        }
                    }
                    else {
                        TSK_DEBUG_INFO("Closing socket with fd = %d because ioctlt() returned zero or failed", active_socket->fd);
                        remove_socket = 1;
                    }

                    if(remove_socket) {
                        fd = active_socket->fd;
                        tnet_transport_remove_socket(transport, &active_socket->fd);
                        TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, fd);
                        continue;
                    }
                    goto TNET_POLLIN_DONE;
                }

                if(len <= 0) {
#if defined(__ANDROID__) || defined(ANDROID)
                    // workaround for indoona OSX which sends bodiless UDP packets
                    // vand Android requires to call recv() even if len is equal to zero
                    if(len == 0 && ret == 0) {
                        static char __fake_buff[1];
                        ret = recv(active_socket->fd, __fake_buff, len, 0);
                    }
#endif
                    goto TNET_POLLIN_DONE;
                }

                if (!(buffer = tsk_calloc(len, sizeof(uint8_t)))) {
                    TSK_DEBUG_ERROR("TSK_CALLOC FAILED");
                    goto TNET_POLLIN_DONE;
                }

                // Retrieve the remote address
                if (TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)) {
                    ret = tnet_getpeername(active_socket->fd, &remote_addr);
                }

                // Receive the waiting data
                if (active_socket->tlshandle) {
                    int isEncrypted;
                    tsk_size_t tlslen = len;
                    if ((ret = tnet_tls_socket_recv(active_socket->tlshandle, &buffer, &tlslen, &isEncrypted)) == 0) {
                        if (isEncrypted) {
                            TSK_FREE(buffer);
                            goto TNET_POLLIN_DONE;
                        }
                        if (ret == 0) {
                            len = ret = tlslen;
                        }
                    }
                }
                else {
                    if (is_stream) {
                        ret = tnet_sockfd_recv(active_socket->fd, buffer, len, 0);
                    }
                    else {
                        ret = tnet_sockfd_recvfrom(active_socket->fd, buffer, len, 0, (struct sockaddr*)&remote_addr);
                    }
                }

                if(ret < 0) {
                    TSK_FREE(buffer);
                    status = tnet_geterrno();
                    // do not remove the socket for i/o pending errors
                    if (status == TNET_ERROR_WOULDBLOCK || status == TNET_ERROR_INPROGRESS || status == TNET_ERROR_EAGAIN) {
                        TSK_DEBUG_WARN("recv returned error code:%d", status);
                    }
                    else {
                        TNET_PRINT_LAST_ERROR("recv/recvfrom have failed");
                        removeSocket(i, context);
                    }
                    goto TNET_POLLIN_DONE;
                }

                if((len != (tsk_size_t)ret) && len) {
                    len = (tsk_size_t)ret;
                    // buffer = tsk_realloc(buffer, len);
                }

                if(len > 0) {
                    transport->bytes_in += len;
                    e = tnet_transport_event_create(event_data, transport->callback_data, active_socket->fd);
                    e->data = buffer, buffer = tsk_null;
                    e->size = len;
                    e->remote_addr = remote_addr;

                    TSK_RUNNABLE_ENQUEUE_OBJECT_SAFE(TSK_RUNNABLE(transport), e);
                }
                TSK_FREE(buffer);

TNET_POLLIN_DONE:
                /*context->ufds[i].revents &= ~TNET_POLLIN*/
                ;
            }


            /*================== TNET_POLLOUT ==================*/
            if(context->ufds[i].revents & TNET_POLLOUT) {
                TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLOUT", transport->description);
                if(!active_socket->connected) {
                    active_socket->connected = tsk_true;
                    TSK_RUNNABLE_ENQUEUE(transport, event_connected, transport->callback_data, active_socket->fd);
                }
                //else{
                context->ufds[i].events &= ~TNET_POLLOUT;
                //}
            }


            /*================== TNET_POLLPRI ==================*/
            if(context->ufds[i].revents & TNET_POLLPRI) {
                TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLPRI", transport->description);
            }

            context->ufds[i].revents = 0;
        }/* for */

done:
        /* unlock context */
        tsk_safeobj_unlock(context);

    } /* while */

bail:

    TSK_DEBUG_INFO("Stopped [%s] server with IP {%s} on port {%d}", transport->description, transport->master->ip, transport->master->port);
    return 0;
}
Example #19
0
int conductElection(chat_node* curNode, udp_Server* curServer, udp_Server* ackServer){
	cout << "Conducting Elections...\n";
	int ret = 0 ;
	int val;
	//Check if your node has the highest port number.
	list<UserInfo>::iterator itr,itr2;
	bool isHighest = true;
	int numMsgReceived = 0;
	list<USERINFO> userList = curNode->getUserList();
#ifdef DEBUG
	cout << curNode->listofUsers.size();
	cout << curNode->listofSockets.size();
#endif
	for(itr = curNode->listofUsers.begin(); itr != curNode->listofUsers.end(); ++itr){
		struct UserInfo user = *itr;

		if((strcmp(user.username,curNode->lead.sName)==0) & (strcmp(user.ipaddress,curNode->lead.sIpAddress)==0) & ((atoi(user.portnum) == curNode->lead.sPort)) ){

			curNode->listofUsers.erase(itr);
			//userList.erase(itr);
			break;
		}
	}

	userList = curNode->getUserList();

	for(itr = userList.begin(); itr != userList.end(); ++itr){
		struct UserInfo user = *itr;

		if((atoi(user.portnum) != curNode->portNum)	| (strcmp((user.ipaddress),curNode->ipAddress)!= 0)){

			if(strcmp(curNode->rxBytes,user.rxBytes) < 0){
				isHighest = false;
				numMsgReceived =  sendElectionMessage(curNode, curServer, ackServer, user, numMsgReceived);


			}else{
				if(strcmp(curNode->rxBytes,user.rxBytes) == 0){
					if(curNode->portNum < atoi(user.portnum)){
						isHighest = false;
						numMsgReceived = sendElectionMessage(curNode, curServer, ackServer, user, numMsgReceived);
					}
				}
			}

		}
	}

	//delete &userList;

	cout << "isHighest:"<<isHighest<<endl;
	cout <<" numMsg Recevied:"<<numMsgReceived <<endl;
	//TODO Declare Yourself as the leader
	//Checking if the size of listofUsers = 2
	if((curNode->listofUsers.size() == 1) || (isHighest == true) || (numMsgReceived == 0)){
		cout << "I am the leader\n";
		curNode->bIsLeader = true;
		curNode->mStatusmap.clear();
		curNode->lastSeqNum = 0;
		curNode->mClientmap.erase(string(curNode->lead.sIpAddress)+":"+to_string(curNode->lead.sPort));
		curNode->listofSockets.clear();
		list<USERINFO> userList = curNode->getUserList();
		for(itr = userList.begin(); itr != userList.end(); ++itr){
			USERINFO user;

			user = *itr;
			addSocket(user.ipaddress,atoi(user.portnum));
			if(!((strcmp(user.ipaddress,curNode->ipAddress)==0) & ((atoi(user.portnum) == curNode->portNum))) ){
				sendLeaderMessage(curNode,curServer,ackServer,user);
			}

		}


		updateLeader(curNode);
		curNode->statusServer = NORMAL_OPERATION;
		MESSAGE leaderMsg;
		string msg = "New Leader elected :" + string(curNode->sUserName);
		strcpy(leaderMsg.sContent,msg.c_str());
		leaderMsg.sType = MESSAGE_TYPE_CHAT;
		curNode->consoleQueue.push(leaderMsg);

	}


	return ret;
}
Example #20
0
int tnet_transport_prepare(tnet_transport_t *transport)
{
	int ret = -1;
	transport_context_t *context;
	tnet_fd_t pipes[2];
	
	if(!transport || !transport->context){
		TSK_DEBUG_ERROR("Invalid parameter.");
		return -1;
	}
	else{
		context = transport->context;
	}
	
	if(transport->prepared){
		TSK_DEBUG_ERROR("Transport already prepared.");
		return -2;
	}

	/* Prepare master */
	if(!transport->master){
		if((transport->master = tnet_socket_create(transport->local_host, transport->req_local_port, transport->type))){
			tsk_strupdate(&transport->local_ip, transport->master->ip);
			transport->bind_local_port = transport->master->port;
		}
		else{
			TSK_DEBUG_ERROR("Failed to create master socket");
			return -3;
		}
	}
	
	/* set events */
	context->events = TNET_POLLIN | TNET_POLLNVAL | TNET_POLLERR;
	if(TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)){
		context->events |= TNET_POLLOUT // emulate WinSock2 FD_CONNECT event
//#if !defined(ANDROID)
//			| TNET_POLLHUP /* FIXME: always present */
//#endif
			;
	}
	
	/* Start listening */
	if(TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)){
		if((ret = tnet_sockfd_listen(transport->master->fd, TNET_MAX_FDS))){
			TNET_PRINT_LAST_ERROR("listen have failed.");
			goto bail;
		}
	}
	
	/* Create and add pipes to the fd_set */
	if((ret = pipe(pipes))){
		TNET_PRINT_LAST_ERROR("Failed to create new pipes.");
		goto bail;
	}
	
	/* set both R and W sides */
	context->pipeR = pipes[0];
	context->pipeW = pipes[1];
	
	/* add R side */
	TSK_DEBUG_INFO("pipeR fd=%d", context->pipeR);
	if((ret = addSocket(context->pipeR, transport->master->type, transport, tsk_true, tsk_false))){
		goto bail;
	}
	
	/* Add the master socket to the context. */
	TSK_DEBUG_INFO("master fd=%d", transport->master->fd);
	// don't take ownership: will be closed by the dctor()
	// otherwise will be closed twice: dctor() and removeSocket()
	if((ret = addSocket(transport->master->fd, transport->master->type, transport, tsk_false, tsk_false))){
		TSK_DEBUG_ERROR("Failed to add master socket");
		goto bail;
	}
	
	transport->prepared = tsk_true;
	
bail:
	return ret;
}