summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ot_udp.c61
1 files changed, 53 insertions, 8 deletions
diff --git a/ot_udp.c b/ot_udp.c
index d3fb82a..b79bc76 100644
--- a/ot_udp.c
+++ b/ot_udp.c
@@ -18,15 +18,40 @@
18#include "trackerlogic.h" 18#include "trackerlogic.h"
19#include "ot_udp.h" 19#include "ot_udp.h"
20#include "ot_stats.h" 20#include "ot_stats.h"
21#include "ot_rijndael.h"
21 22
22static const uint8_t g_static_connid[8] = { 0x23, 0x42, 0x05, 0x17, 0xde, 0x41, 0x50, 0xff }; 23static const uint8_t g_static_connid[8] = { 0x23, 0x42, 0x05, 0x17, 0xde, 0x41, 0x50, 0xff };
24static uint32_t g_rijndael_round_key[44] = {0};
25static uint32_t g_key_of_the_hour[2] = {0};
26static ot_time g_hour_of_the_key;
23 27
24static void udp_make_connectionid( uint32_t * connid, const ot_ip6 remoteip ) { 28static void udp_generate_rijndael_round_key() {
25 /* Touch unused variable */ 29 uint8_t key[16];
26 (void)remoteip; 30 key[0] = random(); key[1] = random(); key[2] = random(); key[3] = random();
31 rijndaelKeySetupEnc128( g_rijndael_round_key, key );
27 32
28 /* Use a static secret for now */ 33 g_key_of_the_hour[0] = random();
29 memcpy( connid, g_static_connid, 8 ); 34 g_hour_of_the_key = g_now_minutes;
35}
36
37/* Generate current and previous connection id for ip */
38static void udp_make_connectionid( uint32_t connid[4], const ot_ip6 remoteip ) {
39 uint32_t plain[4], crypt[4];
40 int age, i;
41
42 if( g_now_minutes + 60 > g_hour_of_the_key ) {
43 g_hour_of_the_key = g_now_minutes;
44 g_key_of_the_hour[1] = g_key_of_the_hour[0];
45 g_key_of_the_hour[0] = random();
46 }
47
48 for( age = 0; age < 1; ++age ) {
49 memcpy( plain, remoteip, sizeof( plain ) );
50 for( i=0; i<4; ++i ) plain[i] ^= g_key_of_the_hour[age];
51 rijndaelEncrypt128( g_rijndael_round_key, (uint8_t*)remoteip, (uint8_t*)crypt );
52 connid[2*age ] = crypt[0] ^ crypt[1];
53 connid[2*age+1] = crypt[2] ^ crypt[3];
54 }
30} 55}
31 56
32/* UDP implementation according to http://xbtt.sourceforge.net/udp_tracker_protocol.html */ 57/* UDP implementation according to http://xbtt.sourceforge.net/udp_tracker_protocol.html */
@@ -35,6 +60,7 @@ int handle_udp6( int64 serversocket, struct ot_workstruct *ws ) {
35 uint32_t *inpacket = (uint32_t*)ws->inbuf; 60 uint32_t *inpacket = (uint32_t*)ws->inbuf;
36 uint32_t *outpacket = (uint32_t*)ws->outbuf; 61 uint32_t *outpacket = (uint32_t*)ws->outbuf;
37 uint32_t numwant, left, event, scopeid; 62 uint32_t numwant, left, event, scopeid;
63 uint32_t connid[4];
38 uint16_t port, remoteport; 64 uint16_t port, remoteport;
39 size_t byte_count, scrape_count; 65 size_t byte_count, scrape_count;
40 66
@@ -44,13 +70,29 @@ int handle_udp6( int64 serversocket, struct ot_workstruct *ws ) {
44 stats_issue_event( EVENT_ACCEPT, FLAG_UDP, (uintptr_t)remoteip ); 70 stats_issue_event( EVENT_ACCEPT, FLAG_UDP, (uintptr_t)remoteip );
45 stats_issue_event( EVENT_READ, FLAG_UDP, byte_count ); 71 stats_issue_event( EVENT_READ, FLAG_UDP, byte_count );
46 72
73 /* Minimum udp tracker packet size, also catches error */
74 if( byte_count < 16 )
75 return 1;
76
77 /* Generate the connection id we give out and expect to and from
78 the requesting ip address, this prevents udp spoofing */
79 udp_make_connectionid( connid, remoteip );
80
47 /* Initialise hash pointer */ 81 /* Initialise hash pointer */
48 ws->hash = NULL; 82 ws->hash = NULL;
49 ws->peer_id = NULL; 83 ws->peer_id = NULL;
50 84
51 /* Minimum udp tracker packet size, also catches error */ 85 /* If action is not a ntohl(a) == a == 0, then we
52 if( byte_count < 16 ) 86 expect the derived connection id in first 64 bit */
87 if( inpacket[2] && ( inpacket[0] != connid[0] || inpacket[1] != connid[1] ) &&
88 ( inpacket[0] != connid[2] || inpacket[1] != connid[3] ) ) {
89 const size_t s = sizeof( "Connection ID missmatch." );
90 outpacket[0] = 3; outpacket[1] = inpacket[3];
91 memcpy( &outpacket[2], "Connection ID missmatch.", s );
92 socket_send6( serversocket, ws->outbuf, 8 + s, remoteip, remoteport, 0 );
93 stats_issue_event( EVENT_CONNID_MISSMATCH, FLAG_UDP, 8 + s );
53 return 1; 94 return 1;
95 }
54 96
55 switch( ntohl( inpacket[2] ) ) { 97 switch( ntohl( inpacket[2] ) ) {
56 case 0: /* This is a connect action */ 98 case 0: /* This is a connect action */
@@ -60,7 +102,8 @@ int handle_udp6( int64 serversocket, struct ot_workstruct *ws ) {
60 102
61 outpacket[0] = 0; 103 outpacket[0] = 0;
62 outpacket[1] = inpacket[3]; 104 outpacket[1] = inpacket[3];
63 udp_make_connectionid( outpacket + 2, remoteip ); 105 outpacket[2] = connid[0];
106 outpacket[3] = connid[1];
64 107
65 socket_send6( serversocket, ws->outbuf, 16, remoteip, remoteport, 0 ); 108 socket_send6( serversocket, ws->outbuf, 16, remoteip, remoteport, 0 );
66 stats_issue_event( EVENT_CONNECT, FLAG_UDP, 16 ); 109 stats_issue_event( EVENT_CONNECT, FLAG_UDP, 16 );
@@ -146,6 +189,8 @@ static void* udp_worker( void * args ) {
146 189
147void udp_init( int64 sock, unsigned int worker_count ) { 190void udp_init( int64 sock, unsigned int worker_count ) {
148 pthread_t thread_id; 191 pthread_t thread_id;
192 if( !g_rijndael_round_key[0] )
193 udp_generate_rijndael_round_key();
149#ifdef _DEBUG 194#ifdef _DEBUG
150 fprintf( stderr, " installing %d workers on udp socket %ld", worker_count, (unsigned long)sock ); 195 fprintf( stderr, " installing %d workers on udp socket %ld", worker_count, (unsigned long)sock );
151#endif 196#endif