Exemplo n.º 1
0
void C4Network2IO::CheckTimeout()
{
    // acquire lock
    CStdLock ConnListLock(&ConnListCSec);
    // check all connections for timeout (use deletion-safe iteration method just in case)
    for (C4Network2IOConnection *pConn = pConnList, *pNext; pConn; pConn = pNext)
    {
        pNext = pConn->pNext;
        // status timeout
        if (!pConn->isClosed() && !pConn->isAccepted())
            if (difftime(time(NULL), pConn->getTimestamp()) > C4NetAcceptTimeout)
            {
                Application.InteractiveThread.ThreadLogS("Network: connection accept timeout to %s:%d", inet_ntoa(pConn->getPeerAddr().sin_addr), htons(pConn->getPeerAddr().sin_port));
                pConn->Close();
            }
        // ping timeout
        if (pConn->isAccepted())
            if ((pConn->getLag() != -1 ? pConn->getLag() : 1000 * difftime(time(NULL), pConn->getTimestamp()))
                    > C4NetPingTimeout)
            {
                Application.InteractiveThread.ThreadLogS("%d %d %d", (int)pConn->getLag(), (int)time(NULL), (int)pConn->getTimestamp());
                Application.InteractiveThread.ThreadLogS("Network: ping timeout to %s:%d", inet_ntoa(pConn->getPeerAddr().sin_addr), htons(pConn->getPeerAddr().sin_port));
                pConn->Close();
            }
        // delayed connection removal
        if (pConn->isClosed())
            if (difftime(time(NULL), pConn->getTimestamp()) > C4NetAcceptTimeout)
                RemoveConnection(pConn);
    }
}
Exemplo n.º 2
0
void	CPHCapture::NetRelcase		(CPhysicsShell *s)
{
    VERIFY( s );
    VERIFY( s->get_ElementByStoreOrder(0) );
    VERIFY( s->get_ElementByStoreOrder(0)->PhysicsRefObject() );
    RemoveConnection(s->get_ElementByStoreOrder(0)->PhysicsRefObject());
}
Exemplo n.º 3
0
bool C4Network2IO::Connect(const C4NetIO::addr_t &addr, C4Network2IOProtocol eProt, const C4ClientCore &nCCore, const char *szPassword) // by main thread
{
    // get network class
    C4NetIO *pNetIO = getNetIO(eProt);
    if (!pNetIO) return false;
    // already connected/connecting?
    if (GetConnectionByConnAddr(addr, pNetIO)) return true;
    // assign new connection ID, peer address isn't known yet
    uint32_t iConnID = iNextConnID++;
    C4NetIO::addr_t paddr;
    ZeroMem(&paddr, sizeof paddr);
    // create connection object and add to list
    C4Network2IOConnection *pConn = new C4Network2IOConnection();
    pConn->Set(pNetIO, eProt, paddr, addr, CS_Connect, szPassword, iConnID);
    pConn->SetCCore(nCCore);
    AddConnection(pConn);
    // connect
    if (!pConn->Connect())
    {
        // show error
        LogF("Network: could not connect to %s:%d using %s: %s", inet_ntoa(addr.sin_addr), htons(addr.sin_port),
             getNetIOName(pNetIO), pNetIO->GetError() ? pNetIO->GetError() : "");
        pNetIO->ResetError();
        // remove class
        RemoveConnection(pConn);
        return false;
    }
    // ok, wait for connection
    return true;
}
Exemplo n.º 4
0
    void CSelectModel::CheckWrite() {
        CONNECTION_LIST temp_list;
        {
            CAutoLock autoLock(&m_lock);
            std::copy(m_Connection_List.begin(), m_Connection_List.end(), std::back_inserter(temp_list));
        }

        fd_set fdread;
        FD_ZERO(&fdread);
        CONNECTION_LIST::iterator itor = temp_list.begin();
        CONNECTION_LIST::iterator iend = temp_list.end();
        if (itor == iend) {
            return;
        }

        s32 maxfdp = 0;
        while (itor != iend) {
            FD_SET((*itor)->sock, &fdread);
            if ((*itor)->sock > maxfdp) {
                maxfdp = (*itor)->sock;
            }
            itor ++;
        }

        maxfdp++;
        struct timeval tv = {0, 10};
        s32 ret = select(maxfdp, NULL, &fdread, NULL, &tv);
        if (0 < ret) {
            itor = temp_list.begin();
            while (itor != iend) {
                CConnection * pConnection = (*itor);
                s32 nSize = pConnection->stream.size();
                if (nSize > 0) {
                    s32 nSendRet  = send(pConnection->sock, pConnection->stream.buff(), pConnection->stream.size(), 0);
                    if (nSendRet < 0) {
                        CSEvent * pEvent = NULL;
                        pEvent = m_EventPool.Create();
                        ASSERT(pEvent);
                        // Client socket closed, add connection break event
                        pEvent->nConnectID = m_ConnectionPool.QueryID(pConnection);
                        pEvent->nEventType = NET_EVENT_CONNECTION_BREAK;
                        pConnection->bShutdown = true;
                        //ECHO_TRACE("Connection %d socket %d closed.", m_ConnectionPool.QueryID((*itor)), (*itor)->sock);
                        shutdown(pConnection->sock, SD_BOTH);
                        closesocket(pConnection->sock);
                        RemoveConnection(pConnection);
                        itor = temp_list.erase(itor);
                        m_Queue[QUENE_TYPE_OUT].add(pEvent);
                        continue;
                    }
                    pConnection->stream.out(nSendRet);
                }

                itor++;
            }
        }
    }
Exemplo n.º 5
0
status_t
PostEvent(bluetooth_device* ndev, void* event, size_t size)
{
    struct hci_event_header* outgoingEvent = (struct hci_event_header*) event;
    status_t err;

    // Take actions on certain type of events.
    switch (outgoingEvent->ecode) {
    case HCI_EVENT_CONN_COMPLETE:
    {
        struct hci_ev_conn_complete* data
            = (struct hci_ev_conn_complete*)(outgoingEvent + 1);

        // TODO: XXX parse handle field
        HciConnection* conn = AddConnection(data->handle, BT_ACL,
                                            data->bdaddr, ndev->index);

        if (conn == NULL)
            panic("no mem for conn desc");
        conn->ndevice = ndev;
        TRACE("%s: Registered connection handle=%#x\n", __func__,
              data->handle);
        break;
    }

    case HCI_EVENT_DISCONNECTION_COMPLETE:
    {
        struct hci_ev_disconnection_complete_reply* data;

        data = (struct hci_ev_disconnection_complete_reply*)
               (outgoingEvent + 1);

        RemoveConnection(data->handle, ndev->index);
        TRACE("%s: unRegistered connection handle=%#x\n", __func__,
              data->handle);
        break;
    }

    }

    // forward to bluetooth server
    port_id port = find_port(BT_USERLAND_PORT_NAME);
    if (port != B_NAME_NOT_FOUND) {

        err = write_port_etc(port, PACK_PORTCODE(BT_EVENT, ndev->index, -1),
                             event, size, B_TIMEOUT, 1 * 1000 * 1000);

        if (err != B_OK)
            ERROR("%s: Error posting userland %s\n", __func__, strerror(err));

    } else {
        ERROR("%s: bluetooth_server not found for posting!\n", __func__);
        err = B_NAME_NOT_FOUND;
    }

    return err;
}
Exemplo n.º 6
0
void MyServer::OnDisconnect(playerid_t pid, MyConnection* connection)
{
    BroadcastTracker.Remove(connection);

    RemoveConnection(connection);

    Broadcast(connection, &MyConnection::TCPRemovePlayer,
        pid);

    Pids.Release(pid);
}
Exemplo n.º 7
0
void C4Network2IO::Clear() // by main thread
{
    // process remaining events
    C4InteractiveThread &Thread = Application.InteractiveThread;
    Thread.ProcessEvents();
    // clear event callbacks
    Thread.ClearCallback(Ev_Net_Conn, this);
    Thread.ClearCallback(Ev_Net_Disconn, this);
    Thread.ClearCallback(Ev_Net_Packet, this);
    // close all connections
    CStdLock ConnListLock(&ConnListCSec);
    for (C4Network2IOConnection *pConn = pConnList, *pNext; pConn; pConn = pNext)
    {
        pNext = pConn->pNext;
        // close
        pConn->Close();
        RemoveConnection(pConn);
    }
    // reset list
    pConnList = NULL;
    ConnListLock.Clear();
    // close net i/o classes
    Thread.RemoveProc(this);
    if (pNetIODiscover) {
        Thread.RemoveProc(pNetIODiscover);
        delete pNetIODiscover;
        pNetIODiscover = NULL;
    }
    if (pNetIO_TCP) {
        Thread.RemoveProc(pNetIO_TCP);
        delete pNetIO_TCP;
        pNetIO_TCP = NULL;
    }
    if (pNetIO_UDP) {
        Thread.RemoveProc(pNetIO_UDP);
        delete pNetIO_UDP;
        pNetIO_UDP = NULL;
    }
    if (pRefServer) {
        Thread.RemoveProc(pRefServer);
        delete pRefServer;
        pRefServer = NULL;
    }
    if (UPnPMgr) {
        delete UPnPMgr;
        UPnPMgr = NULL;
    }
    // remove auto-accepts
    ClearAutoAccept();
    // reset flags
    fAllowConnect = fExclusiveConn = false;
    // reset connection ID
    iNextConnID = 0;
}
Exemplo n.º 8
0
CCachedDBConnections::~CCachedDBConnections()
{
    POSITION p = m_DBCache.GetStartPosition();

    CString strConnect;
    CDatabase *pDB = NULL;
    while (p != NULL)
    {
        m_DBCache.GetNextAssoc(p, strConnect, pDB);
        RemoveConnection(strConnect);
    }
}
Exemplo n.º 9
0
/*
====================
TryCheckConnectionTimes
====================
*/
static void TryCheckConnectionTimes( void ) {
	t_int i;

	if ( server_time >= check_connections_time ) {
		for( i = 0; i < connection_count; ++i ) {
			if ( server_time >= connection_times[i] ) {
				RemoveConnection( i );
				--i;
			}
		}
		check_connections_time = 0;
	}
}
Exemplo n.º 10
0
void Node::AddConnection(Node *otherNode, double val)
{
	// odstraneni pripadne duplicity
	RemoveConnection(otherNode);

	// vytvoreni hrany
	Edge e;
	e.first = this;
	e.second = otherNode;
	e.val = val;

	connections.push_back(e);
	otherNode->connections.push_back(e);
}
Exemplo n.º 11
0
void ConnectionsManager::RemoveConnection(Connection c) {
    RemoveConnection(GetConnectionID(c));
}
Exemplo n.º 12
0
void set_connection(char *sp, char *dh, char *dp, enum event_types type)
{

  int cx;

  /* A connection is identified by the host/port 3-tuple (the source IP
     address is not needed because only one client is handled at a time).
     The connection's status depends on the type of the event that caused
     the update.  The following event type are defined with their effect
     on the connection's status:
           SYN, ACT-REQ, - The connection has begun (is an "active"
           ACT-RSP         connection.  Add it to the table as idle
                           (activity == 0) if a SYN or with request/
                           response activity (activity == 1) for ACT-REQ
                           or ACT-RSP.
           REQ           - Find the connection in the table and mark it with
                           an outstanding request (activity == 1).
           RSP           - Find the connection in the table and mark it with
                           a completed request (activity == 0).
           END           - The connection has ended (is no longer an "active"
                           connection).  Remove it from the table.
  */

  switch (type)
     {   
      case SYN:
      case ACT_REQ:
      case ACT_RSP:
	 {
          cx = AddConnection(sp, dh, dp);
          if (cx < 0)  /* already there */
	     {
              error_state("Add for existing connection");
              return;
             }            
          if (cx > MAX_CONNECTIONS)  /* table overflow */
	     {
              error_state("Active connections exceeds maximum");
              exit (-1);
             } 
          connections[cx].state = type;
          if (type == SYN)
             connections[cx].activity = 0;
          else
             connections[cx].activity = 1;
          break;
	 }    

      case REQ:
	 {
          cx = FindConnection(sp, dh, dp);
          if (cx < 0)  /* not there */
	     {
              error_state("REQ for non-existent connection");
              return;
             }
          if ((connections[cx].state == RSP) ||
              (connections[cx].state == ACT_REQ) ||
              (connections[cx].state == SYN))
	     {
              connections[cx].activity = 1; 
              connections[cx].state = REQ;
             }       
          else
              error_state("REQ in invalid connection state");

          break;
         }

      case RSP:
	 {
          cx = FindConnection(sp, dh, dp);
          if (cx < 0)  /* not there */
	     {
              error_state("RSP for non-existent connection");
              return;
             }
          if ((connections[cx].state == REQ) ||
              (connections[cx].state == ACT_RSP) ||
              (connections[cx].state == SYN))
	     {
              connections[cx].activity = 0; 
              connections[cx].state = RSP;
             }      
          else
              error_state("RSP in invalid connection state");

          break;
         }

      case END:
	 {
          cx = FindConnection(sp, dh, dp);
          if (cx < 0)  /* not there */
	     {
              error_state("End for non-existent connection");
              return;
             }
          connections[cx].activity = 0; 
          connections[cx].state = END;
          cx = RemoveConnection(sp, dh, dp);
          break;
	 }
      default:
      break;

     }
}
Exemplo n.º 13
0
Arquivo: server.c Projeto: cotsog/ihlt
void EnterListener(struct ListenerOptions *opts) {
	/* master file descriptor list */
	fd_set master;
	/* temp file descriptor list for select() */
	fd_set read_fds;
	/* maximum file descriptor number */
	int fdmax;
	/* listening socket descriptor */
	int listener;
	/* for setsockopt() SO_REUSEADDR, below */
	int yes = 1;
	int j;
	struct addrinfo *result, *rp;

	/* clear the master and temp sets */
	FD_ZERO(&master);
	FD_ZERO(&read_fds);

	memset(&opts->hints, 0, sizeof(struct addrinfo));
	opts->hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
	opts->hints.ai_socktype = SOCK_STREAM; /* Datagram socket */
	opts->hints.ai_flags = AI_PASSIVE;

	j = getaddrinfo(opts->nodename, opts->servname, &opts->hints, &result);
	if (j != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(j));
		exit(EXIT_FAILURE);
	}

	/* getaddrinfo() returns a list of address structures.
	 Try each address until we successfully bind(2).
	 If socket(2) (or bind(2)) fails, we (close the socket
	 and) try the next address. */

	for (rp = result; rp != NULL ; rp = rp->ai_next) {
		listener = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
		if (listener == -1)
			continue;

		/*"address already in use" error message */
		if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int))
				== -1)
			goto tryagain;

#ifdef SO_REUSEPORT
		if (setsockopt(listener, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(int))
				== -1)
			goto tryagain;
#endif

		if (bind(listener, rp->ai_addr, rp->ai_addrlen) == 0)
			break; /* Success */

		tryagain: close(listener);
	}

	if (rp == NULL ) { /* No address succeeded */
		fprintf(stderr, "Could not bind\n");
		exit(EXIT_FAILURE);
	}
	freeaddrinfo(result); /* No longer needed */

	/* listen */
	if (listen(listener, SOMAXCONN) == -1) {
		perror("Error opening listener");
		exit(1);
	}

	/* add the listener to the master set */
	FD_SET(listener, &master);
	/* keep track of the biggest file descriptor */
	fdmax = listener; /* so far, it's this one */

	/* loop */
	for (;;) {
		/* copy it */
		read_fds = master;

		if (select(fdmax + 1, &read_fds, NULL, NULL, NULL ) == -1) {
			perror("Error waiting for input");
			exit(1);
		}

		if (FD_ISSET(listener, &read_fds)) { /* we got a new one... */
			/* handle new connections */
			struct ConnectionNode *TempNode = GetNewConnection();
			TempNode->addr_len = sizeof(TempNode->addr);
			if ((TempNode->fd = accept(listener,
					(struct sockaddr *) &TempNode->addr, &TempNode->addr_len))
					== -1) {
				perror("Warning accepting one new connection");
				free(TempNode);
			} else {
				FD_SET(TempNode->fd, &master);
				/* add to master set */
				fdmax = TempNode->fd;
				fdmax = TempNode->fd;

				j = getnameinfo((struct sockaddr *) &TempNode->addr,
						TempNode->addr_len, TempNode->host, NI_MAXHOST, NULL, 0,
						0);

				InsertConnectionBefore(&connections_head, TempNode);
				printf("New connection from %s on socket %d index %d\n",
						TempNode->host, TempNode->fd, TempNode->index);
			}
		}

		/* run through the existing connections looking for data to be read */
		struct ConnectionNode *i = connections_head;
		if (connections_head != NULL )
			do {
				if (FD_ISSET(i->fd, &read_fds)) { /* we got one... */
					/* handle data from a client */
					printf("New data from %s on socket %d index %d\n", i->host,
							i->fd, i->index);
					/* buffer for client data */
					char buf[1024];
					int nbytes;
					if ((nbytes = recv(i->fd, buf, sizeof(buf) - 1, 0)) <= 0) {
						/* got error or connection closed by client */
						if (nbytes == 0)
							/* connection closed */
							printf(
									"socket to %s hung up on socket %d index %d\n",
									i->host, i->fd, i->index);
						else
							perror("Negative recv");
						/* close it... */
						close(i->fd);
						/* remove from master set */
						FD_CLR(i->fd, &master);
						/* step back and remove this connection */
						i = RemoveConnection(i);
						if (i == NULL )
							break;
					} else {
						/* Ensure this is an ansi string */
						buf[nbytes] = '\0';
						ProccessInput(i, buf, nbytes);
					}
				}
				i = i->next;
			} while (i != connections_head);
	}
}
Exemplo n.º 14
0
void C4Network2IO::HandlePacket(char cStatus, const C4PacketBase *pPacket, C4Network2IOConnection *pConn)
{
    // security
    if (!pConn) return;

#define GETPKT(type, name) \
    assert(pPacket); const type &name = \
     static_cast<const type &>(*pPacket);

    switch (cStatus)
    {

    case PID_Conn: // connection request
    {
        if (!pConn->isOpen()) break;
        // get packet
        GETPKT(C4PacketConn, rPkt)
        // set connection ID
        pConn->SetRemoteID(rPkt.getConnID());
        // check auto-accept
        if (doAutoAccept(rPkt.getCCore(), *pConn))
        {
            // send answer back
            C4PacketConnRe pcr(true, false, "auto accept");
            if (!pConn->Send(MkC4NetIOPacket(PID_ConnRe, pcr)))
                pConn->Close();
            // accept
            pConn->SetStatus(CS_HalfAccepted);
            pConn->SetCCore(rPkt.getCCore());
            pConn->SetAutoAccepted();
        }
        // note that this packet will get processed by C4Network2, too (main thread)
    }
    break;

    case PID_ConnRe: // connection request reply
    {
        if (!pConn->isOpen()) break;
        // conn not sent? That's fishy.
        // FIXME: Note this happens if the peer has exclusive connection mode on.
        if (!pConn->isConnSent())
        {
            pConn->Close();
            break;
        }
        // get packet
        GETPKT(C4PacketConnRe, rPkt)
        // auto accept connection
        if (rPkt.isOK())
        {
            if (pConn->isHalfAccepted() && pConn->isAutoAccepted())
                pConn->SetAccepted();
        }
    }
    break;

    case PID_Ping:
    {
        if (!pConn->isOpen()) break;
        GETPKT(C4PacketPing, rPkt)
        // pong
        C4PacketPing PktPong = rPkt;
        pConn->Send(MkC4NetIOPacket(PID_Pong, PktPong));
        // remove received packets from log
        pConn->ClearPacketLog(rPkt.getPacketCounter());
    }
    break;

    case PID_Pong:
    {
        if (!pConn->isOpen()) break;
        GETPKT(C4PacketPing, rPkt);
        // save
        pConn->SetPingTime(rPkt.getTravelTime());
    }
    break;

    case PID_FwdReq:
    {
        GETPKT(C4PacketFwd, rPkt);
        HandleFwdReq(rPkt, pConn);
    }
    break;

    case PID_Fwd:
    {
        GETPKT(C4PacketFwd, rPkt);
        // only received accidently?
        if (!rPkt.DoFwdTo(LCCore.getID())) break;
        // handle
        C4NetIOPacket Packet(rPkt.getData(), pConn->getPeerAddr());
        HandlePacket(Packet, pConn, true);
    }
    break;

    case PID_PostMortem:
    {
        GETPKT(C4PacketPostMortem, rPkt);
        // Get connection
        C4Network2IOConnection *pConn = GetConnectionByID(rPkt.getConnID());
        if (!pConn) return;
        // Handle all packets
        uint32_t iCounter;
        for (iCounter = pConn->getInPacketCounter(); ; iCounter++)
        {
            // Get packet
            const C4NetIOPacket *pPkt = rPkt.getPacket(iCounter);
            if (!pPkt) break;
            // Handle it
            HandlePacket(*pPkt, pConn, true);
        }
        // Log
        if (iCounter > pConn->getInPacketCounter())
            Application.InteractiveThread.ThreadLogS("Network: Recovered %d packets", iCounter - pConn->getInPacketCounter());
        // Remove the connection from our list
        if (!pConn->isClosed())
            pConn->Close();
        RemoveConnection(pConn);
    }
    break;

    }

#undef GETPKT
}
Exemplo n.º 15
0
/*
====================
CMD_Disconnect
====================
*/
static void CMD_Disconnect( const int connectionIndex ) {
	RemoveConnection( connectionIndex );
}
Exemplo n.º 16
0
    void CSelectModel::CheckRead() {
        CONNECTION_LIST temp_list;
        {
            CAutoLock autoLock(&m_lock);
            std::copy(m_Connection_List.begin(), m_Connection_List.end(), std::back_inserter(temp_list));
        }

        fd_set fdread;
        FD_ZERO(&fdread);
        CONNECTION_LIST::iterator itor = temp_list.begin();
        CONNECTION_LIST::iterator iend = temp_list.end();
        if (itor == iend) {
            return;
        }
        s32 maxfdp = 0;
        while (itor != iend) {
            FD_SET((*itor)->sock, &fdread);
            if ((*itor)->sock > maxfdp) {
                maxfdp = (*itor)->sock;
            }
            itor ++;
        }

        maxfdp++;

        // We only care read event
        struct timeval tv = {0, 10};
        s32 ret = select(maxfdp, &fdread, NULL, NULL, &tv);
        if (0 < ret) {
            itor = temp_list.begin();
            char szBuff[BUFF_SIZE] = {0};

            while (itor != iend) {
                if (FD_ISSET((*itor)->sock, &fdread)) {
                    CConnection * pConnection = (*itor);
                    memset(szBuff, 0, sizeof(szBuff));
                    s32 nRevRet = recv(pConnection->sock, szBuff, BUFF_SIZE, 0);
                    CSEvent * pEvent = NULL;
                    pEvent = m_EventPool.Create();
                    ASSERT(pEvent);
                    if (nRevRet <= 0) {
                        // Client socket closed, add connection break event
                        pEvent->nConnectID = m_ConnectionPool.QueryID(pConnection);
                        pEvent->nEventType = NET_EVENT_CONNECTION_BREAK;
                        pConnection->bShutdown = true;
                        //ECHO_TRACE("Connection %d socket %d closed.", m_ConnectionPool.QueryID((*itor)), (*itor)->sock);
                        shutdown(pConnection->sock, SD_BOTH);
                        closesocket(pConnection->sock);
                        RemoveConnection(pConnection);
                        itor = temp_list.erase(itor);
                        m_Queue[QUENE_TYPE_OUT].add(pEvent);
                        continue;
                    } else {
                        pEvent->nConnectID = m_ConnectionPool.QueryID(pConnection);
                        pEvent->nEventType = NET_EVENT_RECV;
                        pEvent->stream.in(szBuff, nRevRet);
                        m_Queue[QUENE_TYPE_OUT].add(pEvent);
                    }
                }

                itor++;
            }
        }
    }