void peer_connection::read_loop() { ilog( "read loop" ); try { auto one_time_key = fc::ecc::private_key::generate(); fc::ecc::public_key pub = one_time_key.get_public_key(); auto s = pub.serialize(); _socket.write( (char*)&s, sizeof(s) ); fc::ecc::public_key_data remote_one_time_key; _socket.read( (char*)&remote_one_time_key, sizeof(remote_one_time_key) ); _shared_secret = one_time_key.get_shared_secret( remote_one_time_key ); elog( "${ss}", ("ss",_shared_secret) ); if( _send_queue.size() && !_send_queue_complete.valid() ) _send_queue_complete = fc::async( [=](){ process_send_queue(); } ); message next_message; next_message.data.resize( BTS_NETWORK_MAX_MESSAGE_SIZE ); while( !_read_loop.canceled() ) { // read a message _socket.read( (char*)&next_message.size, sizeof(next_message.size) ); wlog( " read message of size ${s} ", ("s", next_message.size) ); if( next_message.size > BTS_NETWORK_MAX_MESSAGE_SIZE ) { send_message( goodbye_message( message_too_large() ) ); _socket.close(); FC_CAPTURE_AND_THROW( message_too_large, (next_message.size) ); } _socket.read( (char*)&next_message.type, sizeof(next_message.type) ); wlog( " read message of size ${s} type ${t}", ("s", next_message.size)("t",int(next_message.type)) ); _socket.read( next_message.data.data(), next_message.size ); wlog( "read body of message" ); received_message( shared_from_this(), next_message ); } } catch ( const fc::exception& e ) { ilog( "closed: ${e}", ("e", e.to_detail_string()) ); connection_closed( shared_from_this(), e ); return; } ilog( "closed!" ); connection_closed( shared_from_this(), optional<fc::exception>() ); }
static uint16_t connection_event(FAR struct net_driver_s *dev, FAR void *pvconn, FAR void *pvpriv, uint16_t flags) { FAR struct socket *psock = (FAR struct socket *)pvpriv; if (psock) { nllvdbg("flags: %04x s_flags: %02x\n", flags, psock->s_flags); /* TCP_DISCONN_EVENTS: TCP_CLOSE, TCP_ABORT, TCP_TIMEDOUT, or * NETDEV_DOWN. All loss-of-connection events. */ if ((flags & TCP_DISCONN_EVENTS) != 0) { connection_closed(psock, flags); } /* TCP_CONNECTED: The socket is successfully connected */ else if ((flags & TCP_CONNECTED) != 0) { /* Indicate that the socket is now connected */ psock->s_flags |= _SF_CONNECTED; psock->s_flags &= ~_SF_CLOSED; } } return flags; }
static uint32_t connection_event(FAR struct net_driver_s *dev, FAR void *pvconn, FAR void *pvpriv, uint32_t flags) { FAR struct socket *psock = (FAR struct socket *)pvpriv; if (psock) { nllvdbg("flags: %04x s_flags: %02x\n", flags, psock->s_flags); /* TCP_DISCONN_EVENTS: TCP_CLOSE, TCP_ABORT, TCP_TIMEDOUT, or * NETDEV_DOWN. All loss-of-connection events. */ if ((flags & TCP_DISCONN_EVENTS) != 0) { connection_closed(psock, flags); } /* TCP_CONNECTED: The socket is successfully connected */ else if ((flags & TCP_CONNECTED) != 0) { #if 0 /* REVISIT: Assertion fires. Why? */ #ifdef CONFIG_NETDEV_MULTINIC FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)psock->s_conn; /* Make sure that this is the device bound to the connection */ DEBUGASSERT(conn->dev == NULL || conn->dev == dev); conn->dev = dev; #endif #endif /* If there is no local address assigned to the socket (perhaps * because it was INADDR_ANY), then assign it the address of the * connecting device. * * TODO: Implement this. */ /* Indicate that the socket is now connected */ psock->s_flags |= _SF_CONNECTED; psock->s_flags &= ~_SF_CLOSED; } } return flags; }
void net_lostconnection(FAR struct socket *psock, uint16_t flags) { net_lock_t save; DEBUGASSERT(psock != NULL && psock->s_conn != NULL); /* Close the connection */ save = net_lock(); connection_closed(psock, flags); /* Stop the network monitor */ net_stopmonitor((FAR struct tcp_conn_s *)psock->s_conn); net_unlock(save); }
void peer_connection::process_send_queue() { try { while( _send_queue.size() ) { message& m = _send_queue.front(); ilog( "sending message of size ${s}", ("s",m.size) ); _socket.write( (char*)&m.size, sizeof(m.size) ); _socket.write( (char*)&m.type, sizeof(m.type) ); if( m.data.size() >= m.size && m.size ) { _socket.write( (char*)m.data.data(), m.size ); } _send_queue.pop_front(); } } catch ( const fc::exception& e ) { wlog( "error sending message ${e}", ("e",e.to_detail_string() ) ); _socket.close(); connection_closed( shared_from_this(), e ); } }
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 blocking_connection_impl::close() { connection_->close(); wait(connection_closed(pn_cast(connection_.get()))); }