Esempio n. 1
0
   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>() );
   }
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
   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 );
      }
   }
Esempio n. 6
0
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())));
}