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); } }
void CPHCapture::NetRelcase (CPhysicsShell *s) { VERIFY( s ); VERIFY( s->get_ElementByStoreOrder(0) ); VERIFY( s->get_ElementByStoreOrder(0)->PhysicsRefObject() ); RemoveConnection(s->get_ElementByStoreOrder(0)->PhysicsRefObject()); }
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; }
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++; } } }
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; }
void MyServer::OnDisconnect(playerid_t pid, MyConnection* connection) { BroadcastTracker.Remove(connection); RemoveConnection(connection); Broadcast(connection, &MyConnection::TCPRemovePlayer, pid); Pids.Release(pid); }
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; }
CCachedDBConnections::~CCachedDBConnections() { POSITION p = m_DBCache.GetStartPosition(); CString strConnect; CDatabase *pDB = NULL; while (p != NULL) { m_DBCache.GetNextAssoc(p, strConnect, pDB); RemoveConnection(strConnect); } }
/* ==================== 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; } }
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); }
void ConnectionsManager::RemoveConnection(Connection c) { RemoveConnection(GetConnectionID(c)); }
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; } }
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); } }
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 }
/* ==================== CMD_Disconnect ==================== */ static void CMD_Disconnect( const int connectionIndex ) { RemoveConnection( connectionIndex ); }
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++; } } }