void Socket::recv_all() { static char buf[MAXPACKET]; while(true) { sockaddr addr; socklen_t addrlen = sizeof(struct sockaddr); int len = recvfrom(socket, buf, MAXPACKET, MSG_DONTWAIT, &addr, &addrlen); if(len < 4) break; string s = string((char *)&addr, addrlen); int id; memcpy((void*)&id, (void*)buf, 4); id = ntohl(id); pair<string,int> s_id(s, id); SocketConnection *sc; if(connections.count(s_id) == 0) { if(!listening) continue; sc = new SocketConnection(socket, &addr, addrlen, SERVER_ID, id); new_connections.push(sc); connections[s_id] = sc; } else { sc = connections[s_id]; } sc->recv_data(buf, len); } }
bool SocketAcceptor::onData( SocketServer& server, socket_handle s ) { SocketConnections::iterator i = m_connections.find( s ); if ( i == m_connections.end() ) return false; SocketConnection* pSocketConnection = i->second; return pSocketConnection->read( *this, server ); }
void SocketInitiator::onDisconnect( SocketConnector&, int s ) { QF_STACK_PUSH(SocketInitiator::onDisconnect) SocketConnections::iterator i = m_connections.find( s ); SocketConnections::iterator j = m_pendingConnections.find( s ); SocketConnection* pSocketConnection = 0; if( i != m_connections.end() ) pSocketConnection = i->second; if( j != m_pendingConnections.end() ) pSocketConnection = j->second; if( !pSocketConnection ) return; setDisconnected( pSocketConnection->getSession()->getSessionID() ); Session* pSession = pSocketConnection->getSession(); if ( pSession ) { pSession->disconnect(); setDisconnected( pSession->getSessionID() ); } delete pSocketConnection; m_connections.erase( s ); m_pendingConnections.erase( s ); QF_STACK_POP }
ConnectionPtr SocketConnection::acceptSync() { LB_TS_THREAD( _recvThread ); if( !isListening( )) return 0; LBASSERT( _overlappedAcceptData ); LBASSERT( _overlappedSocket != INVALID_SOCKET ); if( _overlappedSocket == INVALID_SOCKET ) return 0; // complete accept DWORD got = 0; DWORD flags = 0; if( !WSAGetOverlappedResult( _readFD, &_overlappedRead, &got, TRUE, &flags )) { LBWARN << "Accept completion failed: " << lunchbox::sysError << ", closing socket" << std::endl; close(); return 0; } sockaddr_in* local = 0; sockaddr_in* remote = 0; int localLen = 0; int remoteLen = 0; GetAcceptExSockaddrs( _overlappedAcceptData, 0, sizeof( sockaddr_in ) + 16, sizeof( sockaddr_in ) + 16, (sockaddr**)&local, &localLen, (sockaddr**)&remote, &remoteLen ); _tuneSocket( _overlappedSocket ); ConstConnectionDescriptionPtr description = getDescription(); SocketConnection* newConnection = new SocketConnection; ConnectionPtr connection( newConnection ); // to keep ref-counting correct newConnection->_readFD = _overlappedSocket; newConnection->_writeFD = _overlappedSocket; #ifndef _WIN32 //fcntl( _overlappedSocket, F_SETFL, O_NONBLOCK ); #endif newConnection->_initAIORead(); _overlappedSocket = INVALID_SOCKET; newConnection->_setState( STATE_CONNECTED ); ConnectionDescriptionPtr newDescription = newConnection->_getDescription(); newDescription->bandwidth = description->bandwidth; newDescription->port = ntohs( remote->sin_port ); newDescription->setHostname( getHostName( *remote )); LBDEBUG << "accepted connection from " << newDescription->getHostname() << ":" << newDescription->port << std::endl; return connection; }
void OutputSocket::removeFirstConnection() { SocketConnection *connection = this->m_connections[0]; InputSocket *inputSocket = connection->getToSocket(); if (inputSocket != NULL) { inputSocket->setConnection(NULL); } this->m_connections.erase(this->m_connections.begin()); }
bool SocketInitiator::onData( SocketConnector& connector, int s ) { QF_STACK_PUSH(SocketInitiator::onData) SocketConnections::iterator i = m_connections.find( s ); if ( i == m_connections.end() ) return false; SocketConnection* pSocketConnection = i->second; return pSocketConnection->read( connector ); QF_STACK_POP }
SocketConnection *ExecutionSystemHelper::addLink(vector<SocketConnection *>& links, OutputSocket *fromSocket, InputSocket *toSocket) { SocketConnection *newconnection = new SocketConnection(); newconnection->setFromSocket(fromSocket); newconnection->setToSocket(toSocket); fromSocket->addConnection(newconnection); toSocket->setConnection(newconnection); links.push_back(newconnection); return newconnection; }
void SocketInitiator::onWrite( SocketConnector& connector, int s ) { QF_STACK_PUSH(SocketInitiator::onWrite) SocketConnections::iterator i = m_connections.find( s ); if ( i == m_connections.end() ) return ; SocketConnection* pSocketConnection = i->second; if( pSocketConnection->processQueue() ) pSocketConnection->unsignal(); QF_STACK_POP }
void SocketAcceptor::onDisconnect( SocketServer&, socket_handle s ) { SocketConnections::iterator i = m_connections.find( s ); if ( i == m_connections.end() ) return ; SocketConnection* pSocketConnection = i->second; Session* pSession = pSocketConnection->getSession(); if ( pSession ) pSession->disconnect(); delete pSocketConnection; m_connections.erase( s ); }
void SocketConnection::onHeartbeat(int theFd, short theEvt, void *theArg) { SocketConnection* connection = (SocketConnection*) theArg; connection->heartbeatTimerEvtM = NULL; int heartbeatInterval = connection->protocolM->getHeartbeatInterval(); if (heartbeatInterval > 0) { connection->protocolM->asynHandleHeartbeat(connection->fdM, connection->selfM); } connection->startHeartbeatTimer(); }
void SocketInitiator::onConnect( SocketConnector&, int s ) { QF_STACK_PUSH(SocketInitiator::onConnect) SocketConnections::iterator i = m_pendingConnections.find( s ); if( i == m_pendingConnections.end() ) return; SocketConnection* pSocketConnection = i->second; m_connections[s] = pSocketConnection; m_pendingConnections.erase( i ); setConnected( pSocketConnection->getSession()->getSessionID() ); pSocketConnection->onTimeout(); QF_STACK_POP }
WriteBufferOperation *OutputSocket::findAttachedWriteBufferOperation() const { unsigned int index; for (index = 0; index < this->m_connections.size(); index++) { SocketConnection *connection = this->m_connections[index]; NodeBase *node = connection->getToNode(); if (node->isOperation()) { NodeOperation *operation = (NodeOperation *)node; if (operation->isWriteBufferOperation()) { return (WriteBufferOperation *)operation; } } } return NULL; }
gboolean SocketConnection::NegotiateTLSCb(GIOChannel* gio, gboolean isSocketEncrypted, gpointer data, const GError* error) { SocketConnection *socketConnection = reinterpret_cast<SocketConnection *>( data ); // Temp reference to keep SocketConnection reference alive while we're executing it MojRefCountedPtr<SocketConnection> temp(socketConnection); // Note: error should not be freed if(error == NULL && isSocketEncrypted) socketConnection->TLSReady(); else socketConnection->TLSError(error); return true; }
gboolean SocketConnection::SocketConnectCb(GIOChannel* gio, gpointer data, const GError* error) { SocketConnection *socketConnection = reinterpret_cast<SocketConnection *>( data ); assert(data); // Temp reference to keep SocketConnection reference alive while we're executing it MojRefCountedPtr<SocketConnection> temp(socketConnection); // Note: error should not be freed socketConnection->m_connectTimer.Cancel(); if(error == NULL) socketConnection->Connected(); else socketConnection->ConnectError(error); return true; }
void OutputSocket::relinkConnections(OutputSocket *relinkToSocket, bool single) { if (isConnected()) { if (single) { SocketConnection *connection = this->m_connections[0]; connection->setFromSocket(relinkToSocket); relinkToSocket->addConnection(connection); this->m_connections.erase(this->m_connections.begin()); } else { unsigned int index; for (index = 0; index < this->m_connections.size(); index++) { SocketConnection *connection = this->m_connections[index]; connection->setFromSocket(relinkToSocket); relinkToSocket->addConnection(connection); } this->m_connections.clear(); } } }
ConnectionPtr SocketConnection::acceptSync() { if( !isListening( )) return 0; sockaddr_in newAddress; socklen_t newAddressLen = sizeof( newAddress ); Socket fd; unsigned nTries = 1000; do fd = ::accept( _readFD, (sockaddr*)&newAddress, &newAddressLen ); while( fd == INVALID_SOCKET && errno == EINTR && --nTries ); if( fd == INVALID_SOCKET ) { LBWARN << "accept failed: " << lunchbox::sysError << std::endl; return 0; } _tuneSocket( fd ); ConstConnectionDescriptionPtr description = getDescription(); SocketConnection* newConnection = new SocketConnection; newConnection->_readFD = fd; newConnection->_writeFD = fd; newConnection->_setState( STATE_CONNECTED ); ConnectionDescriptionPtr newDescription = newConnection->_getDescription(); newDescription->bandwidth = description->bandwidth; newDescription->port = ntohs( newAddress.sin_port ); newDescription->setHostname( inet_ntoa( newAddress.sin_addr )); LBDEBUG << "Accepted " << newDescription->toString() << std::endl; return newConnection; }
void SocketServer::start() { struct sockaddr_storage remoteaddr; // client address socklen_t addrlen; char remoteIP[INET6_ADDRSTRLEN]; // sigset_t mask; // sigset_t orig_mask; // key = connection id std::map<int, SocketConnection*> connections; // /** // * I'm not sure of this signal handling code, but for now it works: // * I register a signal handler for the process, then in the handler I look if it's a SIGKILL for the thread, then // * flag it as killed. // * The sigmask code, I think, it's for handling correctly a signal while pselect is waiting, then exit from it // */ // struct sigaction act; // // memset (&act, 0, sizeof(act)); // act.sa_handler = signal_handler; // // /* should shut down on SIGTERM. */ // if (sigaction(SIGTERM, &act, 0)) { // perror ("sigaction"); // throw std::exception(); // } // // sigemptyset (&mask); // sigaddset (&mask, SIGPIPE); // // if (sigprocmask(SIG_BLOCK, &mask, &orig_mask) < 0) { // perror ("sigprocmask"); // throw std::exception(); // } // main loop for(;;) { read_fds = master; // copy it if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { perror("select"); exit(4); } int i; // run through the existing connections looking for data to read for(i = 0; i <= fdmax; i++) { if (FD_ISSET(i, &read_fds)) { // we got one!! if (i == listenfd) { // handle new connection addrlen = sizeof remoteaddr; int connfd = accept(listenfd, (struct sockaddr *)&remoteaddr, &addrlen); if (connfd == -1) { perror("accept() error"); } else { FD_SET(connfd, &master); // add to master set if (connfd > fdmax) { // keep track of the max fdmax = connfd; } printf("new connection from %s on " "socket %d\n", inet_ntop(remoteaddr.ss_family, get_in_addr((struct sockaddr*)&remoteaddr), remoteIP, INET6_ADDRSTRLEN), connfd); } } else { // handle data from a client auto found = connections.find(i); if (found == connections.end()) { connections[i] = new SocketConnection(i); } SocketConnection *connection = connections[i]; try { int rcvd; rcvd = connection->read(request_buffer, REQUEST_BUFFER_SIZE); if (rcvd < 0) // receive error { perror("recv() error"); throw std::exception(); } else if (rcvd == 0) { fprintf(stderr,"Client disconnected unexpectedly.\n"); throw std::exception(); } if (data_received(connection, request_buffer, rcvd)) { connections.erase(i); delete(connection); FD_CLR(i, &master); // remove from master set } } catch (std::exception &e) { std::cerr << "exception handling request: " << e.what() << std::endl; connections.erase(i); connection_closed(connection); delete(connection); FD_CLR(i, &master); // remove from master set } } } } } }
void on_read(int theFd, short theEvt, void *theArg) { SocketConnection* connection = (SocketConnection*)theArg; connection->asynRead(theFd, theEvt); }
void on_write(int theFd, short theEvt, void *theArg) { SocketConnection* connection = (SocketConnection*)theArg; connection->asynWrite(theFd, theEvt); }