Ejemplo n.º 1
0
/* process_packet:
 * Callback which processes a packet captured by libpcap. */
void process_packet(u_char *user, const struct pcap_pkthdr *hdr, const u_char *pkt)
{
    struct tcphdr tcp;
    int off, len, delta;
    connection *C, c;
    struct sockaddr_storage src, dst;
    struct sockaddr *s, *d;
    uint8_t proto;
    
    s = (struct sockaddr *)&src;
    d = (struct sockaddr *)&dst;

    if (handle_link_layer(&datalink_info, pkt, hdr->caplen, &proto, &off))
    	return;
	
    if (layer3_find_tcp(pkt, proto, &off, s, d, &tcp))
    	return;

    len = hdr->caplen - off;

    /* XXX fragmented packets and other nasties. */

    /* try to find the connection slot associated with this. */
    C = find_connection(s, d);

    /* no connection at all, so we need to allocate one. */
    if (!C) {
        log_msg(LOG_INFO, "new connection: %s", connection_string(s,d));
        C = alloc_connection();
        *C = connection_new(s, d);
        /* This might or might not be an entirely new connection (SYN flag
         * set). Either way we need a sequence number to start at. */
        (*C)->isn = ntohl(tcp.th_seq);
    }

    /* Now we need to process this segment. */
    c = *C;
    delta = 0;/*tcp.syn ? 1 : 0;*/

    /* NB (STD0007):
     *    SEG.LEN = the number of octets occupied by the data in the
     *    segment (counting SYN and FIN) */
#if 0
    if (tcp.syn)
        /* getting a new isn. */
        c->isn = htonl(tcp.seq);
#endif

    if (tcp.th_flags & TH_RST) {
        /* Looks like this connection is bogus, and so might be a
         * connection going the other way. */
        log_msg(LOG_INFO, "connection reset: %s", connection_string(s, d));

        connection_delete(c);
        *C = NULL;

        if ((C = find_connection(d, s))) {
            connection_delete(*C);
            *C = NULL;
        }

        return;
    }

    if (len > 0) {
        /* We have some data in the packet. If this data occurred after
         * the first data we collected for this connection, then save it
         * so that we can look for images. Otherwise, discard it. */
        unsigned int offset;

        offset = ntohl(tcp.th_seq);

        /* Modulo 2**32 arithmetic; offset = seq - isn + delta. */
        if (offset < (c->isn + delta))
            offset = 0xffffffff - (c->isn + delta - offset);
        else
            offset -= c->isn + delta;

        if (offset > c->len + WRAPLEN) {
            /* Out-of-order packet. */
            log_msg(LOG_INFO, "out of order packet: %s", connection_string(s, d));
        } else {
            connection_push(c, pkt + off, offset, len);
            extract_media(c);
        }
    }
    if (tcp.th_flags & TH_FIN) {
        /* Connection closing; mark it as closed, but let sweep_connections
         * free it if appropriate. */
        log_msg(LOG_INFO, "connection closing: %s, %d bytes transferred", connection_string(s, d), c->len);
        c->fin = 1;
    }

    /* sweep out old connections */
    sweep_connections();
}
Ejemplo n.º 2
0
//-----------------------------------------------------------------------------
// TODO: determine level of detail for return value, i.e. bool or enum
connection_c::error_e connection_c::open( void ) {
  // sanity checks
  if( _open ) return ERROR_NONE;

  assert( _role != UNDEFINED );  

  if( _role == CLIENT || _role == ROUTER ) {  
    // if client or router, build a context
    // Note: for DEALER or WORKER, the context was supplied in construction
    _context = zmq_ctx_new();
    if( _context == NULL ) {
      return ERROR_CONTEXT;
      // Note: no error values are defined for zmq_ctx_new
    }
  }

  // open a socket
  if( _role == CLIENT ) {
    _socket = zmq_socket( _context, ZMQ_REQ );
  } else if( _role == ROUTER ) {
    _socket = zmq_socket( _context, ZMQ_ROUTER );
  } else if( _role == DEALER ) {
    _socket = zmq_socket( _context, ZMQ_DEALER );
  } else if( _role == WORKER ) {
    _socket = zmq_socket( _context, ZMQ_REP );
/*
  } else if( _role == IPC_SERVER ) {
    _socket = zmq_socket( _context, ZMQ_PAIR );
  } else if( _role == IPC_CLIENT ) {
    _socket = zmq_socket( _context, ZMQ_PAIR );
*/
  } else {
    // Note: sanity checks should guarantee never getting here.
    return ERROR_SOCKET;
  }

  // validate socket creation
  if( _socket == NULL ) {
    if( errno == EINVAL ) {
      // the requested socket type is invalid
      return ERROR_SOCKET;
    } else if( errno == EFAULT ) {
      // the provided context is invalid
      return ERROR_CONTEXT;
    } else if( errno == EMFILE ) {
      // the limit on the number of open sockets has been reached
      return ERROR_LIMIT;
    } else if( errno == ETERM ) {
      // the context specified was terminated
      return ERROR_CONTEXT;
    } else {
      // Note: above should trap specifics, but if fall through then return
      // a socket error
      return ERROR_SOCKET;
    }
  }

  //if( _role == CLIENT || _role == WORKER || _role == IPC_CLIENT ) {  
  if( _role == CLIENT || _role == WORKER ) {  
    // if client or worker, connect to the socket
    if( zmq_connect( _socket, connection_string().c_str() ) == -1 ) {
      if( errno == EINVAL ) {
        // endpoint invalid
        return ERROR_ADDRESS;
      } else if( errno == EPROTONOSUPPORT ) {
        // transport protocol is not supported
        return ERROR_SOCKET;
      } else if( errno == ENOCOMPATPROTO ) {
        // transport protocol incompatible with socket
        return ERROR_SOCKET;
      } else if( errno == ETERM ) {
        // zeromq context was terminated
        return ERROR_CONTEXT;
      } else if( errno == ENOTSOCK ) {
        // socket is invalid
        return ERROR_SOCKET;
      } else if( errno == EMTHREAD ) {
        // no I/O thread available
        return ERROR_CONTEXT;
      } else {
        // Note: above should trap specifics, but if fall through then return
        // a socket error  
        return ERROR_SOCKET;
      }
    }
  //} else if( _role == ROUTER || _role == DEALER || _role == IPC_SERVER ) {  
  } else if( _role == ROUTER || _role == DEALER ) {  
    // if router or dealer, bind to the socket
    if( zmq_bind( _socket, connection_string().c_str() ) == -1 ) {
      if( errno == EINVAL ) {
        // endpoint invalid
        return ERROR_ADDRESS;
      } else if( errno == EPROTONOSUPPORT ) {
        // transport protocol is not supported
        return ERROR_SOCKET;
      } else if( errno == ENOCOMPATPROTO ) {
        // transport protocol incompatible with socket
        return ERROR_SOCKET;
      } else if( errno == EADDRINUSE ) {
        // requested address already in use
        return ERROR_ADDRESS;
      } else if( errno == EADDRNOTAVAIL ) {
        // requested address was not local
        return ERROR_ADDRESS;
      } else if( errno == ENODEV ) {
        // requested address specifies a nonexistent interface
        return ERROR_ADDRESS;
      } else if( errno == ETERM ) {
        // zeromq context was terminated
        return ERROR_CONTEXT;
      } else if( errno == ENOTSOCK ) {
        // socket is invalid
        return ERROR_SOCKET;
      } else if( errno == EMTHREAD ) {
        // no I/O thread available
        return ERROR_CONTEXT;
      } else {
        // Note: above should trap specifics, but if fall through then return
        // a socket error  
        return ERROR_SOCKET;
      }
    }
  }

  // otherwise success, socket is open
  _open = true;
  return ERROR_NONE;
}
Ejemplo n.º 3
0
connection::pointer node::get_connection(uint64_t db)
{
	auto cn = m_route.find(db);
	VLOG(2) << "connection: " << cn->connection_string() << ", db: " << db;
	return cn;
}