static int
readPeerId (tr_handshake    * handshake,
            struct evbuffer * inbuf)
{
  bool connected_to_self;
  char client[128];
  uint8_t peer_id[PEER_ID_LEN];
  tr_torrent * tor;

  if (evbuffer_get_length (inbuf) < PEER_ID_LEN)
    return READ_LATER;

  /* peer id */
  tr_peerIoReadBytes (handshake->io, inbuf, peer_id, PEER_ID_LEN);
  tr_peerIoSetPeersId (handshake->io, peer_id);
  handshake->havePeerID = true;
  tr_clientForId (client, sizeof (client), peer_id);
  dbgmsg (handshake, "peer-id is [%s] ... isIncoming is %d", client,
          tr_peerIoIsIncoming (handshake->io));

  /* if we've somehow connected to ourselves, don't keep the connection */
  tor = tr_torrentFindFromHash (handshake->session, tr_peerIoGetTorrentHash (handshake->io));
  connected_to_self = (tor != NULL) && !memcmp (peer_id, tr_torrentGetPeerId(tor), PEER_ID_LEN);

  return tr_handshakeDone (handshake, !connected_to_self);
}
Beispiel #2
0
static int
readPeerId( tr_handshake    * handshake,
            struct evbuffer * inbuf )
{
    tr_bool peerIsGood;
    char client[128];
    tr_torrent * tor;
    const uint8_t * tor_peer_id;
    uint8_t peer_id[PEER_ID_LEN];

    if( evbuffer_get_length( inbuf ) < PEER_ID_LEN )
        return READ_LATER;

    /* peer id */
    tr_peerIoReadBytes( handshake->io, inbuf, peer_id, PEER_ID_LEN );
    tr_peerIoSetPeersId( handshake->io, peer_id );
    handshake->havePeerID = TRUE;
    tr_clientForId( client, sizeof( client ), peer_id );
    dbgmsg( handshake, "peer-id is [%s] ... isIncoming is %d", client,
            tr_peerIoIsIncoming( handshake->io ) );

    /* if we've somehow connected to ourselves, don't keep the connection */
    tor = tr_torrentFindFromHash( handshake->session, tr_peerIoGetTorrentHash( handshake->io ) );
    tor_peer_id = tor && tor->peer_id ? tor->peer_id : tr_getPeerId( );
    peerIsGood = memcmp( peer_id, tor_peer_id, PEER_ID_LEN ) != 0;
    dbgmsg( handshake, "isPeerGood == %d", (int)peerIsGood );
    return tr_handshakeDone( handshake, peerIsGood );
}
static int
parseHandshake (tr_handshake *    handshake,
                struct evbuffer * inbuf)
{
  uint8_t name[HANDSHAKE_NAME_LEN];
  uint8_t reserved[HANDSHAKE_FLAGS_LEN];
  uint8_t hash[SHA_DIGEST_LENGTH];
  tr_torrent * tor;
  uint8_t peer_id[PEER_ID_LEN];

  dbgmsg (handshake, "payload: need %d, got %zu",
          HANDSHAKE_SIZE, evbuffer_get_length (inbuf));

  if (evbuffer_get_length (inbuf) < HANDSHAKE_SIZE)
    return READ_LATER;

  /* confirm the protocol */
  tr_peerIoReadBytes (handshake->io, inbuf, name, HANDSHAKE_NAME_LEN);
  if (memcmp (name, HANDSHAKE_NAME, HANDSHAKE_NAME_LEN))
    return HANDSHAKE_ENCRYPTION_WRONG;

  /* read the reserved bytes */
  tr_peerIoReadBytes (handshake->io, inbuf, reserved, HANDSHAKE_FLAGS_LEN);

  /* torrent hash */
  tr_peerIoReadBytes (handshake->io, inbuf, hash, sizeof (hash));
  assert (tr_peerIoHasTorrentHash (handshake->io));
  if (!tr_torrentExists (handshake->session, hash)
      || memcmp (hash, tr_peerIoGetTorrentHash (handshake->io), SHA_DIGEST_LENGTH))
    {
      dbgmsg (handshake, "peer returned the wrong hash. wtf?");
      return HANDSHAKE_BAD_TORRENT;
    }

  /* peer_id */
  tr_peerIoReadBytes (handshake->io, inbuf, peer_id, sizeof (peer_id));
  tr_peerIoSetPeersId (handshake->io, peer_id);

  /* peer id */
  handshake->havePeerID = true;
  dbgmsg (handshake, "peer-id is [%*.*s]", PEER_ID_LEN, PEER_ID_LEN, peer_id);

  tor = tr_torrentFindFromHash (handshake->session, hash);
  if (!memcmp (peer_id, tr_torrentGetPeerId(tor), PEER_ID_LEN))
    {
      dbgmsg (handshake, "streuth!  we've connected to ourselves.");
      return HANDSHAKE_PEER_IS_SELF;
    }

  /**
  *** Extensions
  **/

  tr_peerIoEnableDHT  (handshake->io, HANDSHAKE_HAS_DHT    (reserved));
  tr_peerIoEnableLTEP (handshake->io, HANDSHAKE_HAS_LTEP    (reserved));
  tr_peerIoEnableFEXT (handshake->io, HANDSHAKE_HAS_FASTEXT (reserved));

  return HANDSHAKE_OK;
}