예제 #1
0
static void
http_callback(http_req_aux_t *req, void *opaque)
{
  char errbuf[128];
  tracker_torrent_t *tt = opaque;
  torrent_t *to = tt->tt_torrent;
  htsmsg_t *msg;
  net_addr_t na;

  assert(tt->tt_http_req != NULL);
  tt->tt_http_req = NULL;

  buf_t *b = http_req_get_result(req);

  tt->tt_interval = MIN(3600, tt->tt_interval * 2);

  if(b != NULL) {
    msg = bencode_deserialize(buf_cstr(b),
                              buf_cstr(b) + buf_size(b),
                              errbuf, sizeof(errbuf), NULL, NULL);
    if(msg != NULL) {

      const char *err = htsmsg_get_str(msg, "failure reason");
      if(err != NULL) {
        tracker_trace(tt->tt_tracker, "%s for %s", err, to->to_title);
        goto done;
      }

      const char *trackerid = htsmsg_get_str(msg, "trackerid");

      if(trackerid != NULL)
        mystrset(&tt->tt_trackerid, trackerid);

      tt->tt_interval =
        htsmsg_get_u32_or_default(msg, "min interval",
                                  htsmsg_get_u32_or_default(msg,
                                                            "interval", 1800));

      htsmsg_t *peers = htsmsg_get_list(msg, "peers");
      if(peers != NULL) {
        htsmsg_field_t *f;
        HTSMSG_FOREACH(f, peers) {
          htsmsg_t *sub = htsmsg_get_map_by_field(f);
          if(sub == NULL)
            continue;
          const char *ip = htsmsg_get_str(sub, "ip");
          if(ip == NULL)
            continue;

          if(net_resolve_numeric(ip, &na))
            continue;

          na.na_port = htsmsg_get_u32_or_default(sub, "port", 0);
          if(na.na_port == 0)
            continue;
          peer_add(to, &na);
        }
      }
예제 #2
0
void protocol_recvpacket(const char *buffer, const int buffer_len,
                         struct udpsrvsession_s *session)
{
  uint16_t len;
  int i;
  void *p;
  const struct protocol_ip *ip = (struct protocol_ip *) buffer;
  struct peer_s *peer;
  if (buffer_len < 4)
    return;
  len = ntohs(ip->tot_len);
#if DEBUG > 2
  log_info("UDP: sizes %d = %d.\n", len, buffer_len);

    if (buffer_len > 27)
    {
      uint16_t *ping = (uint16_t*) &buffer[26];
      log_debug("Ping%d id: %d\n", ip->version, ntohs(*ping));
    }
#endif
  if (ip->version == 4)         //IPv4 packet
    {
      if (session->peer == NULL
          || (session->peer->stat & PEER_STAT_ID) == 0 || buffer_len < 20)
        return;
      if (router_checksrc((struct in_addr *) &ip->daddr, &tun_selfpeer) !=
          0)
        {
          log_debug("Not for me: %s\n",
                    inet_ntoa(*(struct in_addr *) &ip->daddr));
          return;
        }
      if (router_checksrc((struct in_addr *) &ip->saddr, session->peer) !=
          0)
        {
          log_debug("Not from there: %s\n",
                    inet_ntoa(*(struct in_addr *) &ip->saddr));
          return;
        }
      if (len > buffer_len)
        {
          log_error("UDP: Invalid size %d > %d.\n", len, buffer_len);
          return;
        }
      tundev_write(buffer, len);
    }
//else if (ip->version == 6) //IPv6 Packet
  else if (ip->version == PROTOCOL1_V && ip->ihl == 1)  //Internal packets v1
    {
      if (((struct protocol_1_s *) ip)->pid == PROTOCOL1_IDA)
        {
          log_debug("ACK...\n");
          if (session->peer != NULL
              && (session->peer->stat & PEER_STAT_IDK) == 0)
            {
              pthread_mutex_lock(&session->peer->modify_mutex);
              session->peer->stat |= PEER_STAT_IDK;
              pthread_mutex_unlock(&session->peer->modify_mutex);
            }
          if ((session->peer->stat & PEER_STAT_ID) != 0)
            log_info("New peer authenticated.\n");
        }
      else if (((struct protocol_1_s *) ip)->pid == PROTOCOL1_ID)
        {
          log_debug("ID...\n");
          if (session->peer == NULL)
            session->peer = peer_create();
          pthread_mutex_lock(&session->peer->modify_mutex);
          peer = session->peer;
          peer->udpsrvsession = session;
          if ((peer->stat & PEER_STAT_ID) == 0)
            {
              if (protocol_processpeer(peer,
                                       &((struct protocol_1id_s *)
                                         buffer)->peer,
                                       buffer_len -
                                       sizeof(struct protocol_1id_s) +
                                       sizeof(struct protocol_peer_s)) < 0)
                {
                  log_error("invalid ID\n");
                  //-TODO: Check
                  pthread_mutex_unlock(&peer->modify_mutex);
                  peer_destroy(peer);
                  return;
                }
              log_debug("Validating id.\n");
              /* Check for valid routes shared */
              if (protocol_checknameconstraints(peer) < 0)
                {
                  log_debug
                    ("Peer trying to request for unallowed network...\n");
                  pthread_mutex_unlock(&peer->modify_mutex);
                  peer_destroy(peer);
                  return;
                }
              peer->stat |= PEER_STAT_ID;
              timeout_update(&peer->timeout);
              if ((session->peer->stat & PEER_STAT_IDK) != 0)
                log_info("New peer authenticated.\n");
              pthread_mutex_unlock(&peer->modify_mutex);
              if (peer_add(peer, session) < 1)
                {
                  peer_destroy(peer);
                  return;
                }
            }
          //-TODO: JOIN packets
          protocol_sendpacket(session, PROTOCOL1_IDA);
          if ((peer->stat & PEER_STAT_IDK) == 0)
            protocol_sendpacket(session, PROTOCOL1_ID);
        }
      else if (((struct protocol_1_s *) ip)->pid == PROTOCOL1_KA)
        {
          if (len > buffer_len)
            return;
          log_debug("KA...\n");
          if (session->peer != NULL
              && (session->peer->stat & PEER_STAT_ID) != 0)
            {
              timeout_update(&session->peer->timeout);
              p = (void *) buffer + sizeof(struct protocol_1ka_s);
              while (p <= (void *) &buffer[len - 1])
                {
                  peer = peer_create();
                  i =
                    protocol_processpeer(peer,
                                         (struct protocol_peer_s *) p,
                                         (int) ((void *)
                                                &buffer[len - 1] - p));
                  if (i < 0)
                    {
                      peer_destroy(peer);
                      return;
                    }
                  p += i;
                  if (router_existpeer
                      (peer->shared_networks,
                       peer->shared_networks_len) == 0)
                    peer_addnew(peer);
                  else
                    peer_destroy(peer);
                }
            }
        }
      else
        {
          log_error("Unknown paquet\n");
          return;
        }
    }
  else
    {
      log_error("Unknown paquet\n");
      return;
    }
  if (len + 4 <= buffer_len)
    protocol_recvpacket(buffer + len, buffer_len - len, session);
}
예제 #3
0
void tapioca_add_node(int node_id, char* address, int port) {
	peer_add(node_id, address, port);
}