Changeset 9323 for trunk/third-party/dht/dht.c
- Timestamp:
- Oct 19, 2009, 1:21:33 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/third-party/dht/dht.c
r9145 r9323 162 162 const unsigned char *tid, int tid_len, 163 163 const unsigned char *target, int confirm); 164 static int send_ found_nodes(int s, struct sockaddr *sa, int salen,164 static int send_nodes_peers(int s, struct sockaddr *sa, int salen, 165 165 const unsigned char *tid, int tid_len, 166 166 const unsigned char *nodes, int nodes_len, 167 struct peer *peers1, int numpeers1, 168 struct peer *peers2, int numpeers2, 167 169 const unsigned char *token, int token_len); 168 170 static int send_closest_nodes(int s, struct sockaddr *sa, int salen, 169 171 const unsigned char *tid, int tid_len, 170 172 const unsigned char *id, 173 struct peer *peers1, int numpeers1, 174 struct peer *peers2, int numpeers2, 171 175 const unsigned char *token, int token_len); 172 176 static int send_get_peers(int s, struct sockaddr *sa, int salen, … … 177 181 unsigned char *infohas, unsigned short port, 178 182 unsigned char *token, int token_len, int confirm); 179 int send_peers_found(int s, struct sockaddr *sa, int salen,180 unsigned char *tid, int tid_len,181 struct peer *peers1, int numpeers1,182 struct peer *peers2, int numpeers2,183 unsigned char *token, int token_len);184 183 int send_peer_announced(int s, struct sockaddr *sa, int salen, 185 184 unsigned char *tid, int tid_len); … … 895 894 unsigned char tid[4]; 896 895 if(n->pinged >= 3) 896 continue; 897 /* A proposed extension to the protocol consists in 898 omitting the token when storage tables are full. */ 899 if(n->token_len == 0) 897 900 continue; 898 901 if(!n->acked) { … … 1638 1641 debugf("Sending closest nodes.\n"); 1639 1642 send_closest_nodes(s, (struct sockaddr*)&source, sizeof(source), 1640 tid, tid_len, target, NULL, 0); 1643 tid, tid_len, target, 1644 NULL, 0, NULL, 0, NULL, 0); 1641 1645 break; 1642 1646 case GET_PEERS: … … 1648 1652 } else { 1649 1653 struct storage *st = find_storage(info_hash); 1654 unsigned char token[TOKEN_SIZE]; 1655 make_token((unsigned char*)&source.sin_addr, 1656 ntohs(source.sin_port), 1657 0, token); 1650 1658 if(st && st->numpeers > 0) { 1651 1659 int i0, n0, n1; 1652 unsigned char token[TOKEN_SIZE];1653 make_token((unsigned char*)&source.sin_addr,1654 ntohs(source.sin_port),1655 0, token);1656 1660 i0 = random() % st->numpeers; 1657 1661 /* We treat peers as a circular list, and choose 50 … … 1659 1663 n0 = MIN(st->numpeers - i0, 50); 1660 1664 n1 = n0 >= 50 ? 0 : MIN(50, i0); 1661 1662 1665 debugf("Sending found peers (%d).\n", n0 + n1); 1663 send_peers_found(s, (struct sockaddr*)&source, 1664 sizeof(source), tid, tid_len, 1665 st->peers + i0, n0, 1666 st->peers, n1, 1667 token, TOKEN_SIZE); 1668 1666 /* According to the spec, we should not be sending any 1667 nodes in this case. However, this avoids breaking 1668 searches if data is stored at the wrong place, and 1669 is also what libtorrent and uTorrent do. */ 1670 send_closest_nodes(s, (struct sockaddr*)&source, 1671 sizeof(source), tid, tid_len, 1672 info_hash, 1673 st->peers + i0, n0, 1674 st->peers, n1, 1675 token, TOKEN_SIZE); 1669 1676 } else { 1670 unsigned char token[TOKEN_SIZE];1671 make_token((unsigned char*)&source.sin_addr,1672 ntohs(source.sin_port),1673 0, token);1674 1677 debugf("Sending nodes for get_peers.\n"); 1675 1678 send_closest_nodes(s, (struct sockaddr*)&source, 1676 1679 sizeof(source), 1677 1680 tid, tid_len, info_hash, 1681 NULL, 0, NULL, 0, 1678 1682 token, TOKEN_SIZE); 1679 1683 } … … 1991 1995 1992 1996 int 1993 send_ found_nodes(int s, struct sockaddr *sa, int salen,1997 send_nodes_peers(int s, struct sockaddr *sa, int salen, 1994 1998 const unsigned char *tid, int tid_len, 1995 1999 const unsigned char *nodes, int nodes_len, 2000 struct peer *peers1, int numpeers1, 2001 struct peer *peers2, int numpeers2, 1996 2002 const unsigned char *token, int token_len) 1997 2003 { 1998 2004 char buf[2048]; 1999 int i = 0, rc ;2005 int i = 0, rc, j; 2000 2006 rc = snprintf(buf + i, 2048 - i, "d1:rd2:id20:"); INC(i, rc, 2048); 2001 2007 COPY(buf, i, myid, 20, 2048); 2002 if(nodes) { 2008 if(token_len > 0) { 2009 rc = snprintf(buf + i, 2048 - i, "5:token%d:", token_len); 2010 INC(i, rc, 2048); 2011 COPY(buf, i, token, token_len, 2048); 2012 } 2013 if(nodes_len > 0) { 2003 2014 rc = snprintf(buf + i, 2048 - i, "5:nodes%d:", nodes_len); 2004 2015 INC(i, rc, 2048); 2005 2016 COPY(buf, i, nodes, nodes_len, 2048); 2006 2017 } 2007 if(token) { 2008 rc = snprintf(buf + i, 2048 - i, "5:token%d:", token_len); 2009 INC(i, rc, 2048); 2010 COPY(buf, i, token, token_len, 2048); 2018 for(j = 0; j < numpeers1; j++) { 2019 unsigned short swapped = htons(peers1[j].port); 2020 rc = snprintf(buf + i, 2048 - i, "6:"); INC(i, rc, 2048); 2021 COPY(buf, i, peers1[j].ip, 4, 2048); 2022 COPY(buf, i, &swapped, 2, 2048); 2023 } 2024 for(j = 0; j < numpeers2; j++) { 2025 unsigned short swapped = htons(peers2[j].port); 2026 rc = snprintf(buf + i, 2048 - i, "6:"); INC(i, rc, 2048); 2027 COPY(buf, i, peers2[j].ip, 4, 2048); 2028 COPY(buf, i, &swapped, 2, 2048); 2011 2029 } 2012 2030 rc = snprintf(buf + i, 2048 - i, "e1:t%d:", tid_len); INC(i, rc, 2048); … … 2067 2085 const unsigned char *tid, int tid_len, 2068 2086 const unsigned char *id, 2087 struct peer *peers1, int numpeers1, 2088 struct peer *peers2, int numpeers2, 2069 2089 const unsigned char *token, int token_len) 2070 2090 { … … 2081 2101 numnodes = buffer_closest_nodes(nodes, numnodes, id, b); 2082 2102 2083 return send_ found_nodes(s, sa, salen, tid, tid_len,2103 return send_nodes_peers(s, sa, salen, tid, tid_len, 2084 2104 nodes, numnodes * 26, 2105 peers1, numpeers1, peers2, numpeers2, 2085 2106 token, token_len); 2086 2107 } … … 2134 2155 2135 2156 return sendto(s, buf, i, confirm ? 0 : MSG_CONFIRM, sa, salen); 2136 2137 fail:2138 errno = ENOSPC;2139 return -1;2140 }2141 2142 int2143 send_peers_found(int s, struct sockaddr *sa, int salen,2144 unsigned char *tid, int tid_len,2145 struct peer *peers1, int numpeers1,2146 struct peer *peers2, int numpeers2,2147 unsigned char *token, int token_len)2148 {2149 char buf[1400];2150 int i = 0, rc, j;2151 2152 rc = snprintf(buf + i, 1400 - i, "d1:rd2:id20:"); INC(i, rc, 1400);2153 COPY(buf, i, myid, 20, 1400);2154 rc = snprintf(buf + i, 1400 - i, "5:token%d:", token_len); INC(i, rc, 1400);2155 COPY(buf, i, token, token_len, 1400);2156 rc = snprintf(buf + i, 1400 - i, "6:valuesl"); INC(i, rc, 1400);2157 for(j = 0; j < numpeers1; j++) {2158 unsigned short swapped = htons(peers1[j].port);2159 rc = snprintf(buf + i, 1400 - i, "6:"); INC(i, rc, 1400);2160 COPY(buf, i, peers1[j].ip, 4, 1400);2161 COPY(buf, i, &swapped, 2, 1400);2162 }2163 for(j = 0; j < numpeers2; j++) {2164 unsigned short swapped = htons(peers2[j].port);2165 rc = snprintf(buf + i, 1400 - i, "6:"); INC(i, rc, 1400);2166 COPY(buf, i, peers2[j].ip, 4, 1400);2167 COPY(buf, i, &swapped, 2, 1400);2168 }2169 rc = snprintf(buf + i, 1400 - i, "ee1:t%d:", tid_len);2170 INC(i, rc, 1400);2171 COPY(buf, i, tid, tid_len, 1400);2172 ADD_V(buf, i, 512);2173 rc = snprintf(buf + i, 2048 - i, "1:y1:re"); INC(i, rc, 2048);2174 return sendto(s, buf, i, 0, sa, salen);2175 2157 2176 2158 fail: … … 2331 2313 int i = p - buf + 9; 2332 2314 int j = 0; 2333 while(buf[i] == '6' && buf[i + 1] == ':' && i + 8 < buflen) { 2334 if(j + 6 > *values_len) 2315 while(1) { 2316 long l; 2317 char *q; 2318 l = strtol((char*)buf + i, &q, 10); 2319 if(q && *q == ':' && l > 0) { 2320 CHECK(q + 1, l); 2321 if(j + l > *values_len) 2322 break; 2323 i = q + 1 + l - (char*)buf; 2324 /* BEP 32 allows heterogeneous values -- ignore IPv6 */ 2325 if(l != 6) { 2326 debugf("Received weird value -- %d bytes.\n", 2327 (int)l); 2328 continue; 2329 } 2330 memcpy((char*)values_return + j, q + 1, l); 2331 j += l; 2332 } else { 2335 2333 break; 2336 CHECK(buf + i + 2, 6); 2337 memcpy((char*)values_return + j, buf + i + 2, 6); 2338 i += 8; 2339 j += 6; 2334 } 2340 2335 } 2341 2336 if(i >= buflen || buf[i] != 'e')
Note: See TracChangeset
for help on using the changeset viewer.