DatagramPeerIO.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. /**
  2. * @file DatagramPeerIO.c
  3. * @author Ambroz Bizjak <ambrop7@gmail.com>
  4. *
  5. * @section LICENSE
  6. *
  7. * This file is part of BadVPN.
  8. *
  9. * BadVPN is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2
  11. * as published by the Free Software Foundation.
  12. *
  13. * BadVPN is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along
  19. * with this program; if not, write to the Free Software Foundation, Inc.,
  20. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21. */
  22. #include <stdint.h>
  23. #include <misc/debug.h>
  24. #include <system/BLog.h>
  25. #include <client/DatagramPeerIO.h>
  26. #include <generated/blog_channel_DatagramPeerIO.h>
  27. #define DATAGRAMPEERIO_MODE_NONE 0
  28. #define DATAGRAMPEERIO_MODE_CONNECT 1
  29. #define DATAGRAMPEERIO_MODE_BIND 2
  30. #define DATAGRAMPEERIO_COMPONENT_SINK 1
  31. #define DATAGRAMPEERIO_COMPONENT_SOURCE 2
  32. static int init_persistent_io (DatagramPeerIO *o, btime_t latency, PacketPassInterface *recv_userif);
  33. static void free_persistent_io (DatagramPeerIO *o);
  34. static void init_sending (DatagramPeerIO *o, BAddr addr, BIPAddr local_addr);
  35. static void free_sending (DatagramPeerIO *o);
  36. static void init_receiving (DatagramPeerIO *o);
  37. static void free_receiving (DatagramPeerIO *o);
  38. static void error_handler (DatagramPeerIO *o, int component, const void *data);
  39. static void reset_mode (DatagramPeerIO *o);
  40. static void recv_decoder_notifier_handler (DatagramPeerIO *o, uint8_t *data, int data_len);
  41. static void send_encoder_notifier_handler (DatagramPeerIO *o, uint8_t *data, int data_len);
  42. int init_persistent_io (DatagramPeerIO *o, btime_t latency, PacketPassInterface *recv_userif)
  43. {
  44. // init error domain
  45. FlowErrorDomain_Init(&o->domain, (FlowErrorDomain_handler)error_handler, o);
  46. // init encoder group
  47. if (!SPProtoEncoderGroup_Init(&o->encoder_group, o->sp_params)) {
  48. goto fail0;
  49. }
  50. // init sending base
  51. // init disassembler
  52. FragmentProtoDisassembler_Init(&o->send_disassembler, o->reactor, o->payload_mtu, o->spproto_payload_mtu, -1, latency);
  53. // init encoder
  54. if (!SPProtoEncoder_Init(&o->send_encoder, &o->encoder_group, FragmentProtoDisassembler_GetOutput(&o->send_disassembler), BReactor_PendingGroup(o->reactor))) {
  55. BLog(BLOG_ERROR, "SPProtoEncoder_Init failed");
  56. goto fail1;
  57. }
  58. // init notifier
  59. PacketRecvNotifier_Init(&o->send_notifier, SPProtoEncoder_GetOutput(&o->send_encoder));
  60. if (SPPROTO_HAVE_OTP(o->sp_params)) {
  61. PacketRecvNotifier_SetHandler(&o->send_notifier, (PacketRecvNotifier_handler_notify)send_encoder_notifier_handler, o);
  62. }
  63. // init connector
  64. PacketPassConnector_Init(&o->send_connector, o->effective_socket_mtu, BReactor_PendingGroup(o->reactor));
  65. // init buffer
  66. if (!SinglePacketBuffer_Init(&o->send_buffer, PacketRecvNotifier_GetOutput(&o->send_notifier), PacketPassConnector_GetInput(&o->send_connector), BReactor_PendingGroup(o->reactor))) {
  67. BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed");
  68. goto fail2;
  69. }
  70. // init receiving
  71. // init assembler
  72. if (!FragmentProtoAssembler_Init(&o->recv_assembler, o->spproto_payload_mtu, recv_userif, 1, fragmentproto_max_chunks_for_frame(o->spproto_payload_mtu, o->payload_mtu))) {
  73. goto fail3;
  74. }
  75. // init notifier
  76. PacketPassNotifier_Init(&o->recv_notifier, FragmentProtoAssembler_GetInput(&o->recv_assembler));
  77. // init decoder
  78. if (!SPProtoDecoder_Init(&o->recv_decoder, PacketPassNotifier_GetInput(&o->recv_notifier), o->sp_params, 2)) {
  79. goto fail4;
  80. }
  81. // init connector
  82. PacketRecvConnector_Init(&o->recv_connector, o->effective_socket_mtu, BReactor_PendingGroup(o->reactor));
  83. // init buffer
  84. if (!SinglePacketBuffer_Init(&o->recv_buffer, PacketRecvConnector_GetOutput(&o->recv_connector), SPProtoDecoder_GetInput(&o->recv_decoder), BReactor_PendingGroup(o->reactor))) {
  85. goto fail5;
  86. }
  87. return 1;
  88. fail5:
  89. PacketRecvConnector_Free(&o->recv_connector);
  90. SPProtoDecoder_Free(&o->recv_decoder);
  91. fail4:
  92. PacketPassNotifier_Free(&o->recv_notifier);
  93. FragmentProtoAssembler_Free(&o->recv_assembler);
  94. fail3:
  95. SinglePacketBuffer_Free(&o->send_buffer);
  96. fail2:
  97. PacketPassConnector_Free(&o->send_connector);
  98. PacketRecvNotifier_Free(&o->send_notifier);
  99. SPProtoEncoder_Free(&o->send_encoder);
  100. fail1:
  101. FragmentProtoDisassembler_Free(&o->send_disassembler);
  102. fail0a:
  103. SPProtoEncoderGroup_Free(&o->encoder_group);
  104. fail0:
  105. return 0;
  106. }
  107. void free_persistent_io (DatagramPeerIO *o)
  108. {
  109. // free receiving
  110. SinglePacketBuffer_Free(&o->recv_buffer);
  111. PacketRecvConnector_Free(&o->recv_connector);
  112. SPProtoDecoder_Free(&o->recv_decoder);
  113. PacketPassNotifier_Free(&o->recv_notifier);
  114. FragmentProtoAssembler_Free(&o->recv_assembler);
  115. // free sending base
  116. SinglePacketBuffer_Free(&o->send_buffer);
  117. PacketPassConnector_Free(&o->send_connector);
  118. PacketRecvNotifier_Free(&o->send_notifier);
  119. SPProtoEncoder_Free(&o->send_encoder);
  120. FragmentProtoDisassembler_Free(&o->send_disassembler);
  121. // free encoder group
  122. SPProtoEncoderGroup_Free(&o->encoder_group);
  123. }
  124. void init_sending (DatagramPeerIO *o, BAddr addr, BIPAddr local_addr)
  125. {
  126. // init sink
  127. DatagramSocketSink_Init(&o->send_sink, FlowErrorReporter_Create(&o->domain, DATAGRAMPEERIO_COMPONENT_SINK), &o->sock, o->effective_socket_mtu, addr, local_addr);
  128. // connect sink
  129. PacketPassConnector_ConnectOutput(&o->send_connector, DatagramSocketSink_GetInput(&o->send_sink));
  130. }
  131. void free_sending (DatagramPeerIO *o)
  132. {
  133. // disconnect sink
  134. PacketPassConnector_DisconnectOutput(&o->send_connector);
  135. // free sink
  136. DatagramSocketSink_Free(&o->send_sink);
  137. }
  138. void init_receiving (DatagramPeerIO *o)
  139. {
  140. // init source
  141. DatagramSocketSource_Init(&o->recv_source, FlowErrorReporter_Create(&o->domain, DATAGRAMPEERIO_COMPONENT_SOURCE), &o->sock, o->effective_socket_mtu);
  142. // connect source
  143. PacketRecvConnector_ConnectInput(&o->recv_connector, DatagramSocketSource_GetOutput(&o->recv_source));
  144. }
  145. void free_receiving (DatagramPeerIO *o)
  146. {
  147. // disconnect source
  148. PacketRecvConnector_DisconnectInput(&o->recv_connector);
  149. // free source
  150. DatagramSocketSource_Free(&o->recv_source);
  151. }
  152. void error_handler (DatagramPeerIO *o, int component, const void *data)
  153. {
  154. ASSERT(o->mode == DATAGRAMPEERIO_MODE_CONNECT || o->mode == DATAGRAMPEERIO_MODE_BIND)
  155. int error = *((int *)data);
  156. switch (component) {
  157. case DATAGRAMPEERIO_COMPONENT_SINK:
  158. switch (error) {
  159. case DATAGRAMSOCKETSINK_ERROR_BSOCKET:
  160. BLog(BLOG_NOTICE, "sink BSocket error %d", BSocket_GetError(&o->sock));
  161. break;
  162. case DATAGRAMSOCKETSINK_ERROR_WRONGSIZE:
  163. BLog(BLOG_NOTICE, "sink wrong size error");
  164. break;
  165. default:
  166. ASSERT(0);
  167. }
  168. break;
  169. case DATAGRAMPEERIO_COMPONENT_SOURCE:
  170. switch (error) {
  171. case DATAGRAMSOCKETSOURCE_ERROR_BSOCKET:
  172. BLog(BLOG_NOTICE, "source BSocket error %d", BSocket_GetError(&o->sock));
  173. break;
  174. default:
  175. ASSERT(0);
  176. }
  177. break;
  178. default:
  179. ASSERT(0);
  180. }
  181. }
  182. void reset_mode (DatagramPeerIO *o)
  183. {
  184. switch (o->mode) {
  185. case DATAGRAMPEERIO_MODE_NONE:
  186. break;
  187. case DATAGRAMPEERIO_MODE_CONNECT:
  188. // kill mode dead var
  189. DEAD_KILL(o->mode_dead);
  190. // set default mode
  191. o->mode = DATAGRAMPEERIO_MODE_NONE;
  192. // free receiving
  193. free_receiving(o);
  194. // free sending
  195. free_sending(o);
  196. // free socket
  197. BSocket_Free(&o->sock);
  198. break;
  199. case DATAGRAMPEERIO_MODE_BIND:
  200. // kill mode dead var
  201. DEAD_KILL(o->mode_dead);
  202. // set default mode
  203. o->mode = DATAGRAMPEERIO_MODE_NONE;
  204. // remove recv notifier handler
  205. PacketPassNotifier_SetHandler(&o->recv_notifier, NULL, NULL);
  206. // free receiving
  207. free_receiving(o);
  208. // free sending
  209. if (o->bind_sending_up) {
  210. free_sending(o);
  211. }
  212. // free socket
  213. BSocket_Free(&o->sock);
  214. break;
  215. default:
  216. ASSERT(0);
  217. }
  218. }
  219. void recv_decoder_notifier_handler (DatagramPeerIO *o, uint8_t *data, int data_len)
  220. {
  221. ASSERT(o->mode == DATAGRAMPEERIO_MODE_BIND)
  222. // obtain addresses from last received packet
  223. BAddr addr;
  224. BIPAddr local_addr;
  225. DatagramSocketSource_GetLastAddresses(&o->recv_source, &addr, &local_addr);
  226. if (!o->bind_sending_up) {
  227. // init sending
  228. init_sending(o, addr, local_addr);
  229. // set sending up
  230. o->bind_sending_up = 1;
  231. } else {
  232. // update addresses
  233. DatagramSocketSink_SetAddresses(&o->send_sink, addr, local_addr);
  234. }
  235. }
  236. void send_encoder_notifier_handler (DatagramPeerIO *o, uint8_t *data, int data_len)
  237. {
  238. ASSERT(SPPROTO_HAVE_OTP(o->sp_params))
  239. if (o->handler_otp_warning && SPProtoEncoderGroup_GetOTPPosition(&o->encoder_group) == o->handler_otp_warning_num_used) {
  240. o->handler_otp_warning(o->handler_otp_warning_user);
  241. return;
  242. }
  243. }
  244. int DatagramPeerIO_Init (DatagramPeerIO *o, BReactor *reactor, int payload_mtu, int socket_mtu, struct spproto_security_params sp_params, btime_t latency, PacketPassInterface *recv_userif)
  245. {
  246. ASSERT(payload_mtu >= 0)
  247. ASSERT(payload_mtu <= UINT16_MAX)
  248. ASSERT(socket_mtu >= 0)
  249. ASSERT(spproto_validate_security_params(sp_params))
  250. ASSERT(spproto_payload_mtu_for_carrier_mtu(sp_params, socket_mtu) > sizeof(struct fragmentproto_chunk_header))
  251. ASSERT(PacketPassInterface_GetMTU(recv_userif) >= payload_mtu)
  252. // set parameters
  253. o->reactor = reactor;
  254. o->payload_mtu = payload_mtu;
  255. o->sp_params = sp_params;
  256. // init dead var
  257. DEAD_INIT(o->dead);
  258. // calculate SPProto payload MTU
  259. o->spproto_payload_mtu = spproto_payload_mtu_for_carrier_mtu(o->sp_params, socket_mtu);
  260. // calculate effective socket MTU
  261. o->effective_socket_mtu = spproto_carrier_mtu_for_payload_mtu(o->sp_params, o->spproto_payload_mtu);
  262. // set no OTP warning handler
  263. if (SPPROTO_HAVE_OTP(o->sp_params)) {
  264. o->handler_otp_warning = NULL;
  265. }
  266. // set mode none
  267. o->mode = DATAGRAMPEERIO_MODE_NONE;
  268. // init persistent I/O objects
  269. if (!init_persistent_io(o, latency, recv_userif)) {
  270. goto fail1;
  271. }
  272. // init debug object
  273. DebugObject_Init(&o->d_obj);
  274. return 1;
  275. fail1:
  276. return 0;
  277. }
  278. void DatagramPeerIO_Free (DatagramPeerIO *o)
  279. {
  280. // free debug object
  281. DebugObject_Free(&o->d_obj);
  282. // reset mode
  283. reset_mode(o);
  284. // free persistent I/O objects
  285. free_persistent_io(o);
  286. // free dead var
  287. DEAD_KILL(o->dead);
  288. }
  289. PacketPassInterface * DatagramPeerIO_GetSendInput (DatagramPeerIO *o)
  290. {
  291. return FragmentProtoDisassembler_GetInput(&o->send_disassembler);
  292. }
  293. void DatagramPeerIO_Disconnect (DatagramPeerIO *o)
  294. {
  295. // reset mode
  296. reset_mode(o);
  297. }
  298. int DatagramPeerIO_Connect (DatagramPeerIO *o, BAddr addr)
  299. {
  300. ASSERT(BAddr_IsRecognized(&addr) && !BAddr_IsInvalid(&addr))
  301. // reset mode
  302. reset_mode(o);
  303. // init socket
  304. if (BSocket_Init(&o->sock, o->reactor, addr.type, BSOCKET_TYPE_DGRAM) < 0) {
  305. BLog(BLOG_ERROR, "BSocket_Init failed");
  306. goto fail1;
  307. }
  308. // connect the socket
  309. // Windows needs this or receive will fail
  310. if (BSocket_Connect(&o->sock, &addr) < 0) {
  311. BLog(BLOG_ERROR, "BSocket_Connect failed");
  312. goto fail2;
  313. }
  314. // init sending
  315. BIPAddr local_addr;
  316. BIPAddr_InitInvalid(&local_addr);
  317. init_sending(o, addr, local_addr);
  318. // init receiving
  319. init_receiving(o);
  320. // set mode
  321. o->mode = DATAGRAMPEERIO_MODE_CONNECT;
  322. // init mode dead var
  323. DEAD_INIT(o->mode_dead);
  324. return 1;
  325. fail2:
  326. BSocket_Free(&o->sock);
  327. fail1:
  328. return 0;
  329. }
  330. int DatagramPeerIO_Bind (DatagramPeerIO *o, BAddr addr)
  331. {
  332. ASSERT(BAddr_IsRecognized(&addr) && !BAddr_IsInvalid(&addr))
  333. // reset mode
  334. reset_mode(o);
  335. // init socket
  336. if (BSocket_Init(&o->sock, o->reactor, addr.type, BSOCKET_TYPE_DGRAM) < 0) {
  337. BLog(BLOG_ERROR, "BSocket_Init failed");
  338. goto fail1;
  339. }
  340. // bind socket
  341. if (BSocket_Bind(&o->sock, &addr) < 0) {
  342. BLog(BLOG_INFO, "BSocket_Bind failed");
  343. goto fail2;
  344. }
  345. // init receiving
  346. init_receiving(o);
  347. // set recv notifier handler
  348. PacketPassNotifier_SetHandler(&o->recv_notifier, (PacketPassNotifier_handler_notify)recv_decoder_notifier_handler, o);
  349. // set mode
  350. o->mode = DATAGRAMPEERIO_MODE_BIND;
  351. // init mode dead var
  352. DEAD_INIT(o->mode_dead);
  353. // set sending not up
  354. o->bind_sending_up = 0;
  355. return 1;
  356. fail2:
  357. BSocket_Free(&o->sock);
  358. fail1:
  359. return 0;
  360. }
  361. void DatagramPeerIO_Flush (DatagramPeerIO *o)
  362. {
  363. BLog(BLOG_ERROR, "Flushing not implemented");
  364. }
  365. void DatagramPeerIO_SetEncryptionKey (DatagramPeerIO *o, uint8_t *encryption_key)
  366. {
  367. ASSERT(o->sp_params.encryption_mode != SPPROTO_ENCRYPTION_MODE_NONE)
  368. // set sending key
  369. SPProtoEncoderGroup_SetEncryptionKey(&o->encoder_group, encryption_key);
  370. // set receiving key
  371. SPProtoDecoder_SetEncryptionKey(&o->recv_decoder, encryption_key);
  372. }
  373. void DatagramPeerIO_RemoveEncryptionKey (DatagramPeerIO *o)
  374. {
  375. ASSERT(o->sp_params.encryption_mode != SPPROTO_ENCRYPTION_MODE_NONE)
  376. // remove sending key
  377. SPProtoEncoderGroup_RemoveEncryptionKey(&o->encoder_group);
  378. // remove receiving key
  379. SPProtoDecoder_RemoveEncryptionKey(&o->recv_decoder);
  380. }
  381. void DatagramPeerIO_SetOTPSendSeed (DatagramPeerIO *o, uint16_t seed_id, uint8_t *key, uint8_t *iv)
  382. {
  383. ASSERT(SPPROTO_HAVE_OTP(o->sp_params))
  384. // set sending seed
  385. SPProtoEncoderGroup_SetOTPSeed(&o->encoder_group, seed_id, key, iv);
  386. }
  387. void DatagramPeerIO_RemoveOTPSendSeed (DatagramPeerIO *o)
  388. {
  389. ASSERT(SPPROTO_HAVE_OTP(o->sp_params))
  390. // remove sending seed
  391. SPProtoEncoderGroup_RemoveOTPSeed(&o->encoder_group);
  392. }
  393. void DatagramPeerIO_AddOTPRecvSeed (DatagramPeerIO *o, uint16_t seed_id, uint8_t *key, uint8_t *iv)
  394. {
  395. ASSERT(SPPROTO_HAVE_OTP(o->sp_params))
  396. // add receiving seed
  397. SPProtoDecoder_AddOTPSeed(&o->recv_decoder, seed_id, key, iv);
  398. }
  399. void DatagramPeerIO_RemoveOTPRecvSeeds (DatagramPeerIO *o)
  400. {
  401. ASSERT(SPPROTO_HAVE_OTP(o->sp_params))
  402. // remove receiving seeds
  403. SPProtoDecoder_RemoveOTPSeeds(&o->recv_decoder);
  404. }
  405. void DatagramPeerIO_SetOTPWarningHandler (DatagramPeerIO *o, DatagramPeerIO_handler_otp_warning handler, void *user, int num_used)
  406. {
  407. ASSERT(SPPROTO_HAVE_OTP(o->sp_params))
  408. ASSERT(!handler || num_used > 0)
  409. o->handler_otp_warning = handler;
  410. o->handler_otp_warning_user = user;
  411. o->handler_otp_warning_num_used = num_used;
  412. }