udp_proxy.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018
  1. /*
  2. * UDP proxy: emulate an unreliable UDP connexion for DTLS testing
  3. *
  4. * Copyright The Mbed TLS Contributors
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  8. * not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. */
  19. /*
  20. * Warning: this is an internal utility program we use for tests.
  21. * It does break some abstractions from the NET layer, and is thus NOT an
  22. * example of good general usage.
  23. */
  24. #define MBEDTLS_ALLOW_PRIVATE_ACCESS
  25. #include "mbedtls/build_info.h"
  26. #if defined(MBEDTLS_PLATFORM_C)
  27. #include "mbedtls/platform.h"
  28. #else
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <time.h>
  32. #define mbedtls_time time
  33. #define mbedtls_time_t time_t
  34. #define mbedtls_printf printf
  35. #define mbedtls_calloc calloc
  36. #define mbedtls_free free
  37. #define mbedtls_exit exit
  38. #define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
  39. #define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
  40. #endif /* MBEDTLS_PLATFORM_C */
  41. #if !defined(MBEDTLS_NET_C)
  42. int main( void )
  43. {
  44. mbedtls_printf( "MBEDTLS_NET_C not defined.\n" );
  45. mbedtls_exit( 0 );
  46. }
  47. #else
  48. #include "mbedtls/net_sockets.h"
  49. #include "mbedtls/error.h"
  50. #include "mbedtls/ssl.h"
  51. #include "mbedtls/timing.h"
  52. #include <string.h>
  53. /* For select() */
  54. #if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
  55. !defined(EFI32)
  56. #include <winsock2.h>
  57. #include <windows.h>
  58. #if defined(_MSC_VER)
  59. #if defined(_WIN32_WCE)
  60. #pragma comment( lib, "ws2.lib" )
  61. #else
  62. #pragma comment( lib, "ws2_32.lib" )
  63. #endif
  64. #endif /* _MSC_VER */
  65. #else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
  66. #include <sys/time.h>
  67. #include <sys/types.h>
  68. #include <unistd.h>
  69. #endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
  70. #define MAX_MSG_SIZE 16384 + 2048 /* max record/datagram size */
  71. #define DFL_SERVER_ADDR "localhost"
  72. #define DFL_SERVER_PORT "4433"
  73. #define DFL_LISTEN_ADDR "localhost"
  74. #define DFL_LISTEN_PORT "5556"
  75. #define DFL_PACK 0
  76. #if defined(MBEDTLS_TIMING_C)
  77. #define USAGE_PACK \
  78. " pack=%%d default: 0 (don't pack)\n" \
  79. " options: t > 0 (pack for t milliseconds)\n"
  80. #else
  81. #define USAGE_PACK
  82. #endif
  83. #define USAGE \
  84. "\n usage: udp_proxy param=<>...\n" \
  85. "\n acceptable parameters:\n" \
  86. " server_addr=%%s default: localhost\n" \
  87. " server_port=%%d default: 4433\n" \
  88. " listen_addr=%%s default: localhost\n" \
  89. " listen_port=%%d default: 4433\n" \
  90. "\n" \
  91. " duplicate=%%d default: 0 (no duplication)\n" \
  92. " duplicate about 1:N packets randomly\n" \
  93. " delay=%%d default: 0 (no delayed packets)\n" \
  94. " delay about 1:N packets randomly\n" \
  95. " delay_ccs=0/1 default: 0 (don't delay ChangeCipherSpec)\n" \
  96. " delay_cli=%%s Handshake message from client that should be\n"\
  97. " delayed. Possible values are 'ClientHello',\n" \
  98. " 'Certificate', 'CertificateVerify', and\n" \
  99. " 'ClientKeyExchange'.\n" \
  100. " May be used multiple times, even for the same\n"\
  101. " message, in which case the respective message\n"\
  102. " gets delayed multiple times.\n" \
  103. " delay_srv=%%s Handshake message from server that should be\n"\
  104. " delayed. Possible values are 'HelloRequest',\n"\
  105. " 'ServerHello', 'ServerHelloDone', 'Certificate'\n"\
  106. " 'ServerKeyExchange', 'NewSessionTicket',\n"\
  107. " 'HelloVerifyRequest' and ''CertificateRequest'.\n"\
  108. " May be used multiple times, even for the same\n"\
  109. " message, in which case the respective message\n"\
  110. " gets delayed multiple times.\n" \
  111. " drop=%%d default: 0 (no dropped packets)\n" \
  112. " drop about 1:N packets randomly\n" \
  113. " mtu=%%d default: 0 (unlimited)\n" \
  114. " drop packets larger than N bytes\n" \
  115. " bad_ad=0/1 default: 0 (don't add bad ApplicationData)\n" \
  116. " bad_cid=%%d default: 0 (don't corrupt Connection IDs)\n" \
  117. " duplicate 1:N packets containing a CID,\n" \
  118. " modifying CID in first instance of the packet.\n" \
  119. " protect_hvr=0/1 default: 0 (don't protect HelloVerifyRequest)\n" \
  120. " protect_len=%%d default: (don't protect packets of this size)\n" \
  121. " inject_clihlo=0/1 default: 0 (don't inject fake ClientHello)\n" \
  122. "\n" \
  123. " seed=%%d default: (use current time)\n" \
  124. USAGE_PACK \
  125. "\n"
  126. /*
  127. * global options
  128. */
  129. #define MAX_DELAYED_HS 10
  130. static struct options
  131. {
  132. const char *server_addr; /* address to forward packets to */
  133. const char *server_port; /* port to forward packets to */
  134. const char *listen_addr; /* address for accepting client connections */
  135. const char *listen_port; /* port for accepting client connections */
  136. int duplicate; /* duplicate 1 in N packets (none if 0) */
  137. int delay; /* delay 1 packet in N (none if 0) */
  138. int delay_ccs; /* delay ChangeCipherSpec */
  139. char* delay_cli[MAX_DELAYED_HS]; /* handshake types of messages from
  140. * client that should be delayed. */
  141. uint8_t delay_cli_cnt; /* Number of entries in delay_cli. */
  142. char* delay_srv[MAX_DELAYED_HS]; /* handshake types of messages from
  143. * server that should be delayed. */
  144. uint8_t delay_srv_cnt; /* Number of entries in delay_srv. */
  145. int drop; /* drop 1 packet in N (none if 0) */
  146. int mtu; /* drop packets larger than this */
  147. int bad_ad; /* inject corrupted ApplicationData record */
  148. unsigned bad_cid; /* inject corrupted CID record */
  149. int protect_hvr; /* never drop or delay HelloVerifyRequest */
  150. int protect_len; /* never drop/delay packet of the given size*/
  151. int inject_clihlo; /* inject fake ClientHello after handshake */
  152. unsigned pack; /* merge packets into single datagram for
  153. * at most \c merge milliseconds if > 0 */
  154. unsigned int seed; /* seed for "random" events */
  155. } opt;
  156. static void exit_usage( const char *name, const char *value )
  157. {
  158. if( value == NULL )
  159. mbedtls_printf( " unknown option or missing value: %s\n", name );
  160. else
  161. mbedtls_printf( " option %s: illegal value: %s\n", name, value );
  162. mbedtls_printf( USAGE );
  163. mbedtls_exit( 1 );
  164. }
  165. static void get_options( int argc, char *argv[] )
  166. {
  167. int i;
  168. char *p, *q;
  169. opt.server_addr = DFL_SERVER_ADDR;
  170. opt.server_port = DFL_SERVER_PORT;
  171. opt.listen_addr = DFL_LISTEN_ADDR;
  172. opt.listen_port = DFL_LISTEN_PORT;
  173. opt.pack = DFL_PACK;
  174. /* Other members default to 0 */
  175. opt.delay_cli_cnt = 0;
  176. opt.delay_srv_cnt = 0;
  177. memset( opt.delay_cli, 0, sizeof( opt.delay_cli ) );
  178. memset( opt.delay_srv, 0, sizeof( opt.delay_srv ) );
  179. for( i = 1; i < argc; i++ )
  180. {
  181. p = argv[i];
  182. if( ( q = strchr( p, '=' ) ) == NULL )
  183. exit_usage( p, NULL );
  184. *q++ = '\0';
  185. if( strcmp( p, "server_addr" ) == 0 )
  186. opt.server_addr = q;
  187. else if( strcmp( p, "server_port" ) == 0 )
  188. opt.server_port = q;
  189. else if( strcmp( p, "listen_addr" ) == 0 )
  190. opt.listen_addr = q;
  191. else if( strcmp( p, "listen_port" ) == 0 )
  192. opt.listen_port = q;
  193. else if( strcmp( p, "duplicate" ) == 0 )
  194. {
  195. opt.duplicate = atoi( q );
  196. if( opt.duplicate < 0 || opt.duplicate > 20 )
  197. exit_usage( p, q );
  198. }
  199. else if( strcmp( p, "delay" ) == 0 )
  200. {
  201. opt.delay = atoi( q );
  202. if( opt.delay < 0 || opt.delay > 20 || opt.delay == 1 )
  203. exit_usage( p, q );
  204. }
  205. else if( strcmp( p, "delay_ccs" ) == 0 )
  206. {
  207. opt.delay_ccs = atoi( q );
  208. if( opt.delay_ccs < 0 || opt.delay_ccs > 1 )
  209. exit_usage( p, q );
  210. }
  211. else if( strcmp( p, "delay_cli" ) == 0 ||
  212. strcmp( p, "delay_srv" ) == 0 )
  213. {
  214. uint8_t *delay_cnt;
  215. char **delay_list;
  216. size_t len;
  217. char *buf;
  218. if( strcmp( p, "delay_cli" ) == 0 )
  219. {
  220. delay_cnt = &opt.delay_cli_cnt;
  221. delay_list = opt.delay_cli;
  222. }
  223. else
  224. {
  225. delay_cnt = &opt.delay_srv_cnt;
  226. delay_list = opt.delay_srv;
  227. }
  228. if( *delay_cnt == MAX_DELAYED_HS )
  229. {
  230. mbedtls_printf( " too many uses of %s: only %d allowed\n",
  231. p, MAX_DELAYED_HS );
  232. exit_usage( p, NULL );
  233. }
  234. len = strlen( q );
  235. buf = mbedtls_calloc( 1, len + 1 );
  236. if( buf == NULL )
  237. {
  238. mbedtls_printf( " Allocation failure\n" );
  239. exit( 1 );
  240. }
  241. memcpy( buf, q, len + 1 );
  242. delay_list[ (*delay_cnt)++ ] = buf;
  243. }
  244. else if( strcmp( p, "drop" ) == 0 )
  245. {
  246. opt.drop = atoi( q );
  247. if( opt.drop < 0 || opt.drop > 20 || opt.drop == 1 )
  248. exit_usage( p, q );
  249. }
  250. else if( strcmp( p, "pack" ) == 0 )
  251. {
  252. #if defined(MBEDTLS_TIMING_C)
  253. opt.pack = (unsigned) atoi( q );
  254. #else
  255. mbedtls_printf( " option pack only defined if MBEDTLS_TIMING_C is enabled\n" );
  256. exit( 1 );
  257. #endif
  258. }
  259. else if( strcmp( p, "mtu" ) == 0 )
  260. {
  261. opt.mtu = atoi( q );
  262. if( opt.mtu < 0 || opt.mtu > MAX_MSG_SIZE )
  263. exit_usage( p, q );
  264. }
  265. else if( strcmp( p, "bad_ad" ) == 0 )
  266. {
  267. opt.bad_ad = atoi( q );
  268. if( opt.bad_ad < 0 || opt.bad_ad > 1 )
  269. exit_usage( p, q );
  270. }
  271. #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
  272. else if( strcmp( p, "bad_cid" ) == 0 )
  273. {
  274. opt.bad_cid = (unsigned) atoi( q );
  275. }
  276. #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
  277. else if( strcmp( p, "protect_hvr" ) == 0 )
  278. {
  279. opt.protect_hvr = atoi( q );
  280. if( opt.protect_hvr < 0 || opt.protect_hvr > 1 )
  281. exit_usage( p, q );
  282. }
  283. else if( strcmp( p, "protect_len" ) == 0 )
  284. {
  285. opt.protect_len = atoi( q );
  286. if( opt.protect_len < 0 )
  287. exit_usage( p, q );
  288. }
  289. else if( strcmp( p, "inject_clihlo" ) == 0 )
  290. {
  291. opt.inject_clihlo = atoi( q );
  292. if( opt.inject_clihlo < 0 || opt.inject_clihlo > 1 )
  293. exit_usage( p, q );
  294. }
  295. else if( strcmp( p, "seed" ) == 0 )
  296. {
  297. opt.seed = atoi( q );
  298. if( opt.seed == 0 )
  299. exit_usage( p, q );
  300. }
  301. else
  302. exit_usage( p, NULL );
  303. }
  304. }
  305. static const char *msg_type( unsigned char *msg, size_t len )
  306. {
  307. if( len < 1 ) return( "Invalid" );
  308. switch( msg[0] )
  309. {
  310. case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC: return( "ChangeCipherSpec" );
  311. case MBEDTLS_SSL_MSG_ALERT: return( "Alert" );
  312. case MBEDTLS_SSL_MSG_APPLICATION_DATA: return( "ApplicationData" );
  313. case MBEDTLS_SSL_MSG_CID: return( "CID" );
  314. case MBEDTLS_SSL_MSG_HANDSHAKE: break; /* See below */
  315. default: return( "Unknown" );
  316. }
  317. if( len < 13 + 12 ) return( "Invalid handshake" );
  318. /*
  319. * Our handshake message are less than 2^16 bytes long, so they should
  320. * have 0 as the first byte of length, frag_offset and frag_length.
  321. * Otherwise, assume they are encrypted.
  322. */
  323. if( msg[14] || msg[19] || msg[22] ) return( "Encrypted handshake" );
  324. switch( msg[13] )
  325. {
  326. case MBEDTLS_SSL_HS_HELLO_REQUEST: return( "HelloRequest" );
  327. case MBEDTLS_SSL_HS_CLIENT_HELLO: return( "ClientHello" );
  328. case MBEDTLS_SSL_HS_SERVER_HELLO: return( "ServerHello" );
  329. case MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST: return( "HelloVerifyRequest" );
  330. case MBEDTLS_SSL_HS_NEW_SESSION_TICKET: return( "NewSessionTicket" );
  331. case MBEDTLS_SSL_HS_CERTIFICATE: return( "Certificate" );
  332. case MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE: return( "ServerKeyExchange" );
  333. case MBEDTLS_SSL_HS_CERTIFICATE_REQUEST: return( "CertificateRequest" );
  334. case MBEDTLS_SSL_HS_SERVER_HELLO_DONE: return( "ServerHelloDone" );
  335. case MBEDTLS_SSL_HS_CERTIFICATE_VERIFY: return( "CertificateVerify" );
  336. case MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE: return( "ClientKeyExchange" );
  337. case MBEDTLS_SSL_HS_FINISHED: return( "Finished" );
  338. default: return( "Unknown handshake" );
  339. }
  340. }
  341. #if defined(MBEDTLS_TIMING_C)
  342. /* Return elapsed time in milliseconds since the first call */
  343. static unsigned ellapsed_time( void )
  344. {
  345. static int initialized = 0;
  346. static struct mbedtls_timing_hr_time hires;
  347. if( initialized == 0 )
  348. {
  349. (void) mbedtls_timing_get_timer( &hires, 1 );
  350. initialized = 1;
  351. return( 0 );
  352. }
  353. return( mbedtls_timing_get_timer( &hires, 0 ) );
  354. }
  355. typedef struct
  356. {
  357. mbedtls_net_context *ctx;
  358. const char *description;
  359. unsigned packet_lifetime;
  360. unsigned num_datagrams;
  361. unsigned char data[MAX_MSG_SIZE];
  362. size_t len;
  363. } ctx_buffer;
  364. static ctx_buffer outbuf[2];
  365. static int ctx_buffer_flush( ctx_buffer *buf )
  366. {
  367. int ret;
  368. mbedtls_printf( " %05u flush %s: %u bytes, %u datagrams, last %u ms\n",
  369. ellapsed_time(), buf->description,
  370. (unsigned) buf->len, buf->num_datagrams,
  371. ellapsed_time() - buf->packet_lifetime );
  372. ret = mbedtls_net_send( buf->ctx, buf->data, buf->len );
  373. buf->len = 0;
  374. buf->num_datagrams = 0;
  375. return( ret );
  376. }
  377. static unsigned ctx_buffer_time_remaining( ctx_buffer *buf )
  378. {
  379. unsigned const cur_time = ellapsed_time();
  380. if( buf->num_datagrams == 0 )
  381. return( (unsigned) -1 );
  382. if( cur_time - buf->packet_lifetime >= opt.pack )
  383. return( 0 );
  384. return( opt.pack - ( cur_time - buf->packet_lifetime ) );
  385. }
  386. static int ctx_buffer_append( ctx_buffer *buf,
  387. const unsigned char * data,
  388. size_t len )
  389. {
  390. int ret;
  391. if( len > (size_t) INT_MAX )
  392. return( -1 );
  393. if( len > sizeof( buf->data ) )
  394. {
  395. mbedtls_printf( " ! buffer size %u too large (max %u)\n",
  396. (unsigned) len, (unsigned) sizeof( buf->data ) );
  397. return( -1 );
  398. }
  399. if( sizeof( buf->data ) - buf->len < len )
  400. {
  401. if( ( ret = ctx_buffer_flush( buf ) ) <= 0 )
  402. {
  403. mbedtls_printf( "ctx_buffer_flush failed with -%#04x", (unsigned int) -ret );
  404. return( ret );
  405. }
  406. }
  407. memcpy( buf->data + buf->len, data, len );
  408. buf->len += len;
  409. if( ++buf->num_datagrams == 1 )
  410. buf->packet_lifetime = ellapsed_time();
  411. return( (int) len );
  412. }
  413. #endif /* MBEDTLS_TIMING_C */
  414. static int dispatch_data( mbedtls_net_context *ctx,
  415. const unsigned char * data,
  416. size_t len )
  417. {
  418. int ret;
  419. #if defined(MBEDTLS_TIMING_C)
  420. ctx_buffer *buf = NULL;
  421. if( opt.pack > 0 )
  422. {
  423. if( outbuf[0].ctx == ctx )
  424. buf = &outbuf[0];
  425. else if( outbuf[1].ctx == ctx )
  426. buf = &outbuf[1];
  427. if( buf == NULL )
  428. return( -1 );
  429. return( ctx_buffer_append( buf, data, len ) );
  430. }
  431. #endif /* MBEDTLS_TIMING_C */
  432. ret = mbedtls_net_send( ctx, data, len );
  433. if( ret < 0 )
  434. {
  435. mbedtls_printf( "net_send returned -%#04x\n", (unsigned int) -ret );
  436. }
  437. return( ret );
  438. }
  439. typedef struct
  440. {
  441. mbedtls_net_context *dst;
  442. const char *way;
  443. const char *type;
  444. unsigned len;
  445. unsigned char buf[MAX_MSG_SIZE];
  446. } packet;
  447. /* Print packet. Outgoing packets come with a reason (forward, dupl, etc.) */
  448. void print_packet( const packet *p, const char *why )
  449. {
  450. #if defined(MBEDTLS_TIMING_C)
  451. if( why == NULL )
  452. mbedtls_printf( " %05u dispatch %s %s (%u bytes)\n",
  453. ellapsed_time(), p->way, p->type, p->len );
  454. else
  455. mbedtls_printf( " %05u dispatch %s %s (%u bytes): %s\n",
  456. ellapsed_time(), p->way, p->type, p->len, why );
  457. #else
  458. if( why == NULL )
  459. mbedtls_printf( " dispatch %s %s (%u bytes)\n",
  460. p->way, p->type, p->len );
  461. else
  462. mbedtls_printf( " dispatch %s %s (%u bytes): %s\n",
  463. p->way, p->type, p->len, why );
  464. #endif
  465. fflush( stdout );
  466. }
  467. /*
  468. * In order to test the server's behaviour when receiving a ClientHello after
  469. * the connection is established (this could be a hard reset from the client,
  470. * but the server must not drop the existing connection before establishing
  471. * client reachability, see RFC 6347 Section 4.2.8), we memorize the first
  472. * ClientHello we see (which can't have a cookie), then replay it after the
  473. * first ApplicationData record - then we're done.
  474. *
  475. * This is controlled by the inject_clihlo option.
  476. *
  477. * We want an explicit state and a place to store the packet.
  478. */
  479. typedef enum {
  480. ICH_INIT, /* haven't seen the first ClientHello yet */
  481. ICH_CACHED, /* cached the initial ClientHello */
  482. ICH_INJECTED, /* ClientHello already injected, done */
  483. } inject_clihlo_state_t;
  484. static inject_clihlo_state_t inject_clihlo_state;
  485. static packet initial_clihlo;
  486. int send_packet( const packet *p, const char *why )
  487. {
  488. int ret;
  489. mbedtls_net_context *dst = p->dst;
  490. /* save initial ClientHello? */
  491. if( opt.inject_clihlo != 0 &&
  492. inject_clihlo_state == ICH_INIT &&
  493. strcmp( p->type, "ClientHello" ) == 0 )
  494. {
  495. memcpy( &initial_clihlo, p, sizeof( packet ) );
  496. inject_clihlo_state = ICH_CACHED;
  497. }
  498. /* insert corrupted CID record? */
  499. if( opt.bad_cid != 0 &&
  500. strcmp( p->type, "CID" ) == 0 &&
  501. ( rand() % opt.bad_cid ) == 0 )
  502. {
  503. unsigned char buf[MAX_MSG_SIZE];
  504. memcpy( buf, p->buf, p->len );
  505. /* The CID resides at offset 11 in the DTLS record header. */
  506. buf[11] ^= 1;
  507. print_packet( p, "modified CID" );
  508. if( ( ret = dispatch_data( dst, buf, p->len ) ) <= 0 )
  509. {
  510. mbedtls_printf( " ! dispatch returned %d\n", ret );
  511. return( ret );
  512. }
  513. }
  514. /* insert corrupted ApplicationData record? */
  515. if( opt.bad_ad &&
  516. strcmp( p->type, "ApplicationData" ) == 0 )
  517. {
  518. unsigned char buf[MAX_MSG_SIZE];
  519. memcpy( buf, p->buf, p->len );
  520. if( p->len <= 13 )
  521. {
  522. mbedtls_printf( " ! can't corrupt empty AD record" );
  523. }
  524. else
  525. {
  526. ++buf[13];
  527. print_packet( p, "corrupted" );
  528. }
  529. if( ( ret = dispatch_data( dst, buf, p->len ) ) <= 0 )
  530. {
  531. mbedtls_printf( " ! dispatch returned %d\n", ret );
  532. return( ret );
  533. }
  534. }
  535. print_packet( p, why );
  536. if( ( ret = dispatch_data( dst, p->buf, p->len ) ) <= 0 )
  537. {
  538. mbedtls_printf( " ! dispatch returned %d\n", ret );
  539. return( ret );
  540. }
  541. /* Don't duplicate Application Data, only handshake covered */
  542. if( opt.duplicate != 0 &&
  543. strcmp( p->type, "ApplicationData" ) != 0 &&
  544. rand() % opt.duplicate == 0 )
  545. {
  546. print_packet( p, "duplicated" );
  547. if( ( ret = dispatch_data( dst, p->buf, p->len ) ) <= 0 )
  548. {
  549. mbedtls_printf( " ! dispatch returned %d\n", ret );
  550. return( ret );
  551. }
  552. }
  553. /* Inject ClientHello after first ApplicationData */
  554. if( opt.inject_clihlo != 0 &&
  555. inject_clihlo_state == ICH_CACHED &&
  556. strcmp( p->type, "ApplicationData" ) == 0 )
  557. {
  558. print_packet( &initial_clihlo, "injected" );
  559. if( ( ret = dispatch_data( dst, initial_clihlo.buf,
  560. initial_clihlo.len ) ) <= 0 )
  561. {
  562. mbedtls_printf( " ! dispatch returned %d\n", ret );
  563. return( ret );
  564. }
  565. inject_clihlo_state = ICH_INJECTED;
  566. }
  567. return( 0 );
  568. }
  569. #define MAX_DELAYED_MSG 5
  570. static size_t prev_len;
  571. static packet prev[MAX_DELAYED_MSG];
  572. void clear_pending( void )
  573. {
  574. memset( &prev, 0, sizeof( prev ) );
  575. prev_len = 0;
  576. }
  577. void delay_packet( packet *delay )
  578. {
  579. if( prev_len == MAX_DELAYED_MSG )
  580. return;
  581. memcpy( &prev[prev_len++], delay, sizeof( packet ) );
  582. }
  583. int send_delayed()
  584. {
  585. uint8_t offset;
  586. int ret;
  587. for( offset = 0; offset < prev_len; offset++ )
  588. {
  589. ret = send_packet( &prev[offset], "delayed" );
  590. if( ret != 0 )
  591. return( ret );
  592. }
  593. clear_pending();
  594. return( 0 );
  595. }
  596. /*
  597. * Avoid dropping or delaying a packet that was already dropped or delayed
  598. * ("held") twice: this only results in uninteresting timeouts. We can't rely
  599. * on type to identify packets, since during renegotiation they're all
  600. * encrypted. So, rely on size mod 2048 (which is usually just size).
  601. *
  602. * We only hold packets at the level of entire datagrams, not at the level
  603. * of records. In particular, if the peer changes the way it packs multiple
  604. * records into a single datagram, we don't necessarily count the number of
  605. * times a record has been held correctly. However, the only known reason
  606. * why a peer would change datagram packing is disabling the latter on
  607. * retransmission, in which case we'd hold involved records at most
  608. * HOLD_MAX + 1 times.
  609. */
  610. static unsigned char held[2048] = { 0 };
  611. #define HOLD_MAX 2
  612. int handle_message( const char *way,
  613. mbedtls_net_context *dst,
  614. mbedtls_net_context *src )
  615. {
  616. int ret;
  617. packet cur;
  618. size_t id;
  619. uint8_t delay_idx;
  620. char ** delay_list;
  621. uint8_t delay_list_len;
  622. /* receive packet */
  623. if( ( ret = mbedtls_net_recv( src, cur.buf, sizeof( cur.buf ) ) ) <= 0 )
  624. {
  625. mbedtls_printf( " ! mbedtls_net_recv returned %d\n", ret );
  626. return( ret );
  627. }
  628. cur.len = ret;
  629. cur.type = msg_type( cur.buf, cur.len );
  630. cur.way = way;
  631. cur.dst = dst;
  632. print_packet( &cur, NULL );
  633. id = cur.len % sizeof( held );
  634. if( strcmp( way, "S <- C" ) == 0 )
  635. {
  636. delay_list = opt.delay_cli;
  637. delay_list_len = opt.delay_cli_cnt;
  638. }
  639. else
  640. {
  641. delay_list = opt.delay_srv;
  642. delay_list_len = opt.delay_srv_cnt;
  643. }
  644. /* Check if message type is in the list of messages
  645. * that should be delayed */
  646. for( delay_idx = 0; delay_idx < delay_list_len; delay_idx++ )
  647. {
  648. if( delay_list[ delay_idx ] == NULL )
  649. continue;
  650. if( strcmp( delay_list[ delay_idx ], cur.type ) == 0 )
  651. {
  652. /* Delay message */
  653. delay_packet( &cur );
  654. /* Remove entry from list */
  655. mbedtls_free( delay_list[delay_idx] );
  656. delay_list[delay_idx] = NULL;
  657. return( 0 );
  658. }
  659. }
  660. /* do we want to drop, delay, or forward it? */
  661. if( ( opt.mtu != 0 &&
  662. cur.len > (unsigned) opt.mtu ) ||
  663. ( opt.drop != 0 &&
  664. strcmp( cur.type, "CID" ) != 0 &&
  665. strcmp( cur.type, "ApplicationData" ) != 0 &&
  666. ! ( opt.protect_hvr &&
  667. strcmp( cur.type, "HelloVerifyRequest" ) == 0 ) &&
  668. cur.len != (size_t) opt.protect_len &&
  669. held[id] < HOLD_MAX &&
  670. rand() % opt.drop == 0 ) )
  671. {
  672. ++held[id];
  673. }
  674. else if( ( opt.delay_ccs == 1 &&
  675. strcmp( cur.type, "ChangeCipherSpec" ) == 0 ) ||
  676. ( opt.delay != 0 &&
  677. strcmp( cur.type, "CID" ) != 0 &&
  678. strcmp( cur.type, "ApplicationData" ) != 0 &&
  679. ! ( opt.protect_hvr &&
  680. strcmp( cur.type, "HelloVerifyRequest" ) == 0 ) &&
  681. cur.len != (size_t) opt.protect_len &&
  682. held[id] < HOLD_MAX &&
  683. rand() % opt.delay == 0 ) )
  684. {
  685. ++held[id];
  686. delay_packet( &cur );
  687. }
  688. else
  689. {
  690. /* forward and possibly duplicate */
  691. if( ( ret = send_packet( &cur, "forwarded" ) ) != 0 )
  692. return( ret );
  693. /* send previously delayed messages if any */
  694. ret = send_delayed();
  695. if( ret != 0 )
  696. return( ret );
  697. }
  698. return( 0 );
  699. }
  700. int main( int argc, char *argv[] )
  701. {
  702. int ret = 1;
  703. int exit_code = MBEDTLS_EXIT_FAILURE;
  704. uint8_t delay_idx;
  705. mbedtls_net_context listen_fd, client_fd, server_fd;
  706. #if defined( MBEDTLS_TIMING_C )
  707. struct timeval tm;
  708. #endif
  709. struct timeval *tm_ptr = NULL;
  710. int nb_fds;
  711. fd_set read_fds;
  712. mbedtls_net_init( &listen_fd );
  713. mbedtls_net_init( &client_fd );
  714. mbedtls_net_init( &server_fd );
  715. get_options( argc, argv );
  716. /*
  717. * Decisions to drop/delay/duplicate packets are pseudo-random: dropping
  718. * exactly 1 in N packets would lead to problems when a flight has exactly
  719. * N packets: the same packet would be dropped on every resend.
  720. *
  721. * In order to be able to reproduce problems reliably, the seed may be
  722. * specified explicitly.
  723. */
  724. if( opt.seed == 0 )
  725. {
  726. opt.seed = (unsigned int) time( NULL );
  727. mbedtls_printf( " . Pseudo-random seed: %u\n", opt.seed );
  728. }
  729. srand( opt.seed );
  730. /*
  731. * 0. "Connect" to the server
  732. */
  733. mbedtls_printf( " . Connect to server on UDP/%s/%s ...",
  734. opt.server_addr, opt.server_port );
  735. fflush( stdout );
  736. if( ( ret = mbedtls_net_connect( &server_fd, opt.server_addr, opt.server_port,
  737. MBEDTLS_NET_PROTO_UDP ) ) != 0 )
  738. {
  739. mbedtls_printf( " failed\n ! mbedtls_net_connect returned %d\n\n", ret );
  740. goto exit;
  741. }
  742. mbedtls_printf( " ok\n" );
  743. /*
  744. * 1. Setup the "listening" UDP socket
  745. */
  746. mbedtls_printf( " . Bind on UDP/%s/%s ...",
  747. opt.listen_addr, opt.listen_port );
  748. fflush( stdout );
  749. if( ( ret = mbedtls_net_bind( &listen_fd, opt.listen_addr, opt.listen_port,
  750. MBEDTLS_NET_PROTO_UDP ) ) != 0 )
  751. {
  752. mbedtls_printf( " failed\n ! mbedtls_net_bind returned %d\n\n", ret );
  753. goto exit;
  754. }
  755. mbedtls_printf( " ok\n" );
  756. /*
  757. * 2. Wait until a client connects
  758. */
  759. accept:
  760. mbedtls_net_free( &client_fd );
  761. mbedtls_printf( " . Waiting for a remote connection ..." );
  762. fflush( stdout );
  763. if( ( ret = mbedtls_net_accept( &listen_fd, &client_fd,
  764. NULL, 0, NULL ) ) != 0 )
  765. {
  766. mbedtls_printf( " failed\n ! mbedtls_net_accept returned %d\n\n", ret );
  767. goto exit;
  768. }
  769. mbedtls_printf( " ok\n" );
  770. /*
  771. * 3. Forward packets forever (kill the process to terminate it)
  772. */
  773. clear_pending();
  774. memset( held, 0, sizeof( held ) );
  775. nb_fds = client_fd.fd;
  776. if( nb_fds < server_fd.fd )
  777. nb_fds = server_fd.fd;
  778. if( nb_fds < listen_fd.fd )
  779. nb_fds = listen_fd.fd;
  780. ++nb_fds;
  781. #if defined(MBEDTLS_TIMING_C)
  782. if( opt.pack > 0 )
  783. {
  784. outbuf[0].ctx = &server_fd;
  785. outbuf[0].description = "S <- C";
  786. outbuf[0].num_datagrams = 0;
  787. outbuf[0].len = 0;
  788. outbuf[1].ctx = &client_fd;
  789. outbuf[1].description = "S -> C";
  790. outbuf[1].num_datagrams = 0;
  791. outbuf[1].len = 0;
  792. }
  793. #endif /* MBEDTLS_TIMING_C */
  794. while( 1 )
  795. {
  796. #if defined(MBEDTLS_TIMING_C)
  797. if( opt.pack > 0 )
  798. {
  799. unsigned max_wait_server, max_wait_client, max_wait;
  800. max_wait_server = ctx_buffer_time_remaining( &outbuf[0] );
  801. max_wait_client = ctx_buffer_time_remaining( &outbuf[1] );
  802. max_wait = (unsigned) -1;
  803. if( max_wait_server == 0 )
  804. ctx_buffer_flush( &outbuf[0] );
  805. else
  806. max_wait = max_wait_server;
  807. if( max_wait_client == 0 )
  808. ctx_buffer_flush( &outbuf[1] );
  809. else
  810. {
  811. if( max_wait_client < max_wait )
  812. max_wait = max_wait_client;
  813. }
  814. if( max_wait != (unsigned) -1 )
  815. {
  816. tm.tv_sec = max_wait / 1000;
  817. tm.tv_usec = ( max_wait % 1000 ) * 1000;
  818. tm_ptr = &tm;
  819. }
  820. else
  821. {
  822. tm_ptr = NULL;
  823. }
  824. }
  825. #endif /* MBEDTLS_TIMING_C */
  826. FD_ZERO( &read_fds );
  827. FD_SET( server_fd.fd, &read_fds );
  828. FD_SET( client_fd.fd, &read_fds );
  829. FD_SET( listen_fd.fd, &read_fds );
  830. if( ( ret = select( nb_fds, &read_fds, NULL, NULL, tm_ptr ) ) < 0 )
  831. {
  832. perror( "select" );
  833. goto exit;
  834. }
  835. if( FD_ISSET( listen_fd.fd, &read_fds ) )
  836. goto accept;
  837. if( FD_ISSET( client_fd.fd, &read_fds ) )
  838. {
  839. if( ( ret = handle_message( "S <- C",
  840. &server_fd, &client_fd ) ) != 0 )
  841. goto accept;
  842. }
  843. if( FD_ISSET( server_fd.fd, &read_fds ) )
  844. {
  845. if( ( ret = handle_message( "S -> C",
  846. &client_fd, &server_fd ) ) != 0 )
  847. goto accept;
  848. }
  849. }
  850. exit_code = MBEDTLS_EXIT_SUCCESS;
  851. exit:
  852. #ifdef MBEDTLS_ERROR_C
  853. if( exit_code != MBEDTLS_EXIT_SUCCESS )
  854. {
  855. char error_buf[100];
  856. mbedtls_strerror( ret, error_buf, 100 );
  857. mbedtls_printf( "Last error was: -0x%04X - %s\n\n", (unsigned int) -ret, error_buf );
  858. fflush( stdout );
  859. }
  860. #endif
  861. for( delay_idx = 0; delay_idx < MAX_DELAYED_HS; delay_idx++ )
  862. {
  863. mbedtls_free( opt.delay_cli[delay_idx] );
  864. mbedtls_free( opt.delay_srv[delay_idx] );
  865. }
  866. mbedtls_net_free( &client_fd );
  867. mbedtls_net_free( &server_fd );
  868. mbedtls_net_free( &listen_fd );
  869. #if defined(_WIN32)
  870. mbedtls_printf( " Press Enter to exit this program.\n" );
  871. fflush( stdout ); getchar();
  872. #endif
  873. mbedtls_exit( exit_code );
  874. }
  875. #endif /* MBEDTLS_NET_C */