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); } }
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); }
void tapioca_add_node(int node_id, char* address, int port) { peer_add(node_id, address, port); }