udpgw.c 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  1. /**
  2. * @file udpgw.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 <inttypes.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <stdarg.h>
  26. #include <stdlib.h>
  27. #include <protocol/udpgw_proto.h>
  28. #include <misc/debug.h>
  29. #include <misc/version.h>
  30. #include <misc/loggers_string.h>
  31. #include <misc/loglevel.h>
  32. #include <misc/offset.h>
  33. #include <misc/byteorder.h>
  34. #include <misc/bsize.h>
  35. #include <structure/LinkedList1.h>
  36. #include <structure/BAVL.h>
  37. #include <base/BLog.h>
  38. #include <system/BReactor.h>
  39. #include <system/BNetwork.h>
  40. #include <system/BConnection.h>
  41. #include <system/BDatagram.h>
  42. #include <system/BSignal.h>
  43. #include <flow/PacketProtoDecoder.h>
  44. #include <flow/PacketPassFairQueue.h>
  45. #include <flow/PacketStreamSender.h>
  46. #include <flow/PacketProtoFlow.h>
  47. #include <flow/SinglePacketBuffer.h>
  48. #ifndef BADVPN_USE_WINAPI
  49. #include <base/BLog_syslog.h>
  50. #endif
  51. #include <udpgw/udpgw.h>
  52. #include <generated/blog_channel_udpgw.h>
  53. #define LOGGER_STDOUT 1
  54. #define LOGGER_SYSLOG 2
  55. struct client {
  56. BConnection con;
  57. BAddr addr;
  58. BTimer disconnect_timer;
  59. PacketProtoDecoder recv_decoder;
  60. PacketPassInterface recv_if;
  61. PacketPassFairQueue send_queue;
  62. PacketStreamSender send_sender;
  63. BAVL connections_tree;
  64. LinkedList1 connections_list;
  65. int num_connections;
  66. LinkedList1 closing_connections_list;
  67. LinkedList1Node clients_list_node;
  68. };
  69. struct connection {
  70. struct client *client;
  71. uint16_t conid;
  72. BAddr addr;
  73. const uint8_t *first_data;
  74. int first_data_len;
  75. int closing;
  76. BPending first_job;
  77. BufferWriter *send_if;
  78. PacketProtoFlow send_ppflow;
  79. PacketPassFairQueueFlow send_qflow;
  80. union {
  81. struct {
  82. BDatagram udp_dgram;
  83. BufferWriter udp_send_writer;
  84. PacketBuffer udp_send_buffer;
  85. SinglePacketBuffer udp_recv_buffer;
  86. PacketPassInterface udp_recv_if;
  87. BAVLNode connections_tree_node;
  88. LinkedList1Node connections_list_node;
  89. };
  90. struct {
  91. LinkedList1Node closing_connections_list_node;
  92. };
  93. };
  94. };
  95. // command-line options
  96. struct {
  97. int help;
  98. int version;
  99. int logger;
  100. #ifndef BADVPN_USE_WINAPI
  101. char *logger_syslog_facility;
  102. char *logger_syslog_ident;
  103. #endif
  104. int loglevel;
  105. int loglevels[BLOG_NUM_CHANNELS];
  106. char *listen_addrs[MAX_LISTEN_ADDRS];
  107. int num_listen_addrs;
  108. int udp_mtu;
  109. int max_clients;
  110. int max_connections_for_client;
  111. int client_socket_sndbuf;
  112. } options;
  113. // MTUs
  114. int udpgw_mtu;
  115. int pp_mtu;
  116. // listen addresses
  117. BAddr listen_addrs[MAX_LISTEN_ADDRS];
  118. int num_listen_addrs;
  119. // reactor
  120. BReactor ss;
  121. // listeners
  122. BListener listeners[MAX_LISTEN_ADDRS];
  123. int num_listeners;
  124. // clients
  125. LinkedList1 clients_list;
  126. int num_clients;
  127. static void print_help (const char *name);
  128. static void print_version (void);
  129. static int parse_arguments (int argc, char *argv[]);
  130. static int process_arguments (void);
  131. static void signal_handler (void *unused);
  132. static void listener_handler (BListener *listener);
  133. static void client_free (struct client *client);
  134. static void client_logfunc (struct client *client);
  135. static void client_log (struct client *client, int level, const char *fmt, ...);
  136. static void client_disconnect_timer_handler (struct client *client);
  137. static void client_connection_handler (struct client *client, int event);
  138. static void client_decoder_handler_error (struct client *client);
  139. static void client_recv_if_handler_send (struct client *client, uint8_t *data, int data_len);
  140. static void connection_init (struct client *client, uint16_t conid, BAddr addr, const uint8_t *data, int data_len);
  141. static void connection_free (struct connection *con);
  142. static void connection_logfunc (struct connection *con);
  143. static void connection_log (struct connection *con, int level, const char *fmt, ...);
  144. static void connection_free_udp (struct connection *con);
  145. static void connection_first_job_handler (struct connection *con);
  146. static int connection_send_to_client (struct connection *con, uint8_t flags, const uint8_t *data, int data_len);
  147. static int connection_send_to_udp (struct connection *con, const uint8_t *data, int data_len);
  148. static void connection_close (struct connection *con);
  149. static void connection_send_qflow_busy_handler (struct connection *con);
  150. static void connection_dgram_handler_event (struct connection *con, int event);
  151. static void connection_udp_recv_if_handler_send (struct connection *con, uint8_t *data, int data_len);
  152. static struct connection * find_connection (struct client *client, uint16_t conid);
  153. static int uint16_comparator (void *unused, uint16_t *v1, uint16_t *v2);
  154. int main (int argc, char **argv)
  155. {
  156. if (argc <= 0) {
  157. return 1;
  158. }
  159. // parse command-line arguments
  160. if (!parse_arguments(argc, argv)) {
  161. fprintf(stderr, "Failed to parse arguments\n");
  162. print_help(argv[0]);
  163. goto fail0;
  164. }
  165. // handle --help and --version
  166. if (options.help) {
  167. print_version();
  168. print_help(argv[0]);
  169. return 0;
  170. }
  171. if (options.version) {
  172. print_version();
  173. return 0;
  174. }
  175. // initialize logger
  176. switch (options.logger) {
  177. case LOGGER_STDOUT:
  178. BLog_InitStdout();
  179. break;
  180. #ifndef BADVPN_USE_WINAPI
  181. case LOGGER_SYSLOG:
  182. if (!BLog_InitSyslog(options.logger_syslog_ident, options.logger_syslog_facility)) {
  183. fprintf(stderr, "Failed to initialize syslog logger\n");
  184. goto fail0;
  185. }
  186. break;
  187. #endif
  188. default:
  189. ASSERT(0);
  190. }
  191. // configure logger channels
  192. for (int i = 0; i < BLOG_NUM_CHANNELS; i++) {
  193. if (options.loglevels[i] >= 0) {
  194. BLog_SetChannelLoglevel(i, options.loglevels[i]);
  195. }
  196. else if (options.loglevel >= 0) {
  197. BLog_SetChannelLoglevel(i, options.loglevel);
  198. }
  199. }
  200. BLog(BLOG_NOTICE, "initializing "GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION);
  201. // initialize network
  202. if (!BNetwork_GlobalInit()) {
  203. BLog(BLOG_ERROR, "BNetwork_GlobalInit failed");
  204. goto fail1;
  205. }
  206. // process arguments
  207. if (!process_arguments()) {
  208. BLog(BLOG_ERROR, "Failed to process arguments");
  209. goto fail1;
  210. }
  211. // compute MTUs
  212. if ((udpgw_mtu = udpgw_compute_mtu(options.udp_mtu)) < 0 ||
  213. udpgw_mtu > PACKETPROTO_MAXPAYLOAD
  214. ) {
  215. BLog(BLOG_ERROR, "MTU is too big");
  216. goto fail1;
  217. }
  218. pp_mtu = udpgw_mtu + sizeof(struct packetproto_header);
  219. // init time
  220. BTime_Init();
  221. // init reactor
  222. if (!BReactor_Init(&ss)) {
  223. BLog(BLOG_ERROR, "BReactor_Init failed");
  224. goto fail1;
  225. }
  226. // setup signal handler
  227. if (!BSignal_Init(&ss, signal_handler, NULL)) {
  228. BLog(BLOG_ERROR, "BSignal_Init failed");
  229. goto fail2;
  230. }
  231. // initialize listeners
  232. num_listeners = 0;
  233. while (num_listeners < num_listen_addrs) {
  234. if (!BListener_Init(&listeners[num_listeners], listen_addrs[num_listeners], &ss, &listeners[num_listeners], (BListener_handler)listener_handler)) {
  235. BLog(BLOG_ERROR, "Listener_Init failed");
  236. goto fail3;
  237. }
  238. num_listeners++;
  239. }
  240. // init clients list
  241. LinkedList1_Init(&clients_list);
  242. num_clients = 0;
  243. // enter event loop
  244. BLog(BLOG_NOTICE, "entering event loop");
  245. BReactor_Exec(&ss);
  246. // free clients
  247. while (!LinkedList1_IsEmpty(&clients_list)) {
  248. struct client *client = UPPER_OBJECT(LinkedList1_GetFirst(&clients_list), struct client, clients_list_node);
  249. client_free(client);
  250. }
  251. fail3:
  252. // free listeners
  253. while (num_listeners > 0) {
  254. num_listeners--;
  255. BListener_Free(&listeners[num_listeners]);
  256. }
  257. // finish signal handling
  258. BSignal_Finish();
  259. fail2:
  260. // free reactor
  261. BReactor_Free(&ss);
  262. fail1:
  263. // free logger
  264. BLog(BLOG_NOTICE, "exiting");
  265. BLog_Free();
  266. fail0:
  267. // finish debug objects
  268. DebugObjectGlobal_Finish();
  269. return 1;
  270. }
  271. void print_help (const char *name)
  272. {
  273. printf(
  274. "Usage:\n"
  275. " %s\n"
  276. " [--help]\n"
  277. " [--version]\n"
  278. " [--logger <"LOGGERS_STRING">]\n"
  279. #ifndef BADVPN_USE_WINAPI
  280. " (logger=syslog?\n"
  281. " [--syslog-facility <string>]\n"
  282. " [--syslog-ident <string>]\n"
  283. " )\n"
  284. #endif
  285. " [--loglevel <0-5/none/error/warning/notice/info/debug>]\n"
  286. " [--channel-loglevel <channel-name> <0-5/none/error/warning/notice/info/debug>] ...\n"
  287. " [--listen-addr <addr>] ...\n"
  288. " [--udp-mtu <bytes>]\n"
  289. " [--max-clients <number>]\n"
  290. " [--max-connections-for-client <number>]\n"
  291. " [--client-socket-sndbuf <bytes / 0>]\n"
  292. "Address format is a.b.c.d:port (IPv4) or [addr]:port (IPv6).\n",
  293. name
  294. );
  295. }
  296. void print_version (void)
  297. {
  298. printf(GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION"\n"GLOBAL_COPYRIGHT_NOTICE"\n");
  299. }
  300. int parse_arguments (int argc, char *argv[])
  301. {
  302. if (argc <= 0) {
  303. return 0;
  304. }
  305. options.help = 0;
  306. options.version = 0;
  307. options.logger = LOGGER_STDOUT;
  308. #ifndef BADVPN_USE_WINAPI
  309. options.logger_syslog_facility = "daemon";
  310. options.logger_syslog_ident = argv[0];
  311. #endif
  312. options.loglevel = -1;
  313. for (int i = 0; i < BLOG_NUM_CHANNELS; i++) {
  314. options.loglevels[i] = -1;
  315. }
  316. options.num_listen_addrs = 0;
  317. options.udp_mtu = DEFAULT_UDP_MTU;
  318. options.max_clients = DEFAULT_MAX_CLIENTS;
  319. options.max_connections_for_client = DEFAULT_MAX_CONNECTIONS_FOR_CLIENT;
  320. options.client_socket_sndbuf = CLIENT_DEFAULT_SOCKET_SEND_BUFFER;
  321. int i;
  322. for (i = 1; i < argc; i++) {
  323. char *arg = argv[i];
  324. if (!strcmp(arg, "--help")) {
  325. options.help = 1;
  326. }
  327. else if (!strcmp(arg, "--version")) {
  328. options.version = 1;
  329. }
  330. else if (!strcmp(arg, "--logger")) {
  331. if (1 >= argc - i) {
  332. fprintf(stderr, "%s: requires an argument\n", arg);
  333. return 0;
  334. }
  335. char *arg2 = argv[i + 1];
  336. if (!strcmp(arg2, "stdout")) {
  337. options.logger = LOGGER_STDOUT;
  338. }
  339. #ifndef BADVPN_USE_WINAPI
  340. else if (!strcmp(arg2, "syslog")) {
  341. options.logger = LOGGER_SYSLOG;
  342. }
  343. #endif
  344. else {
  345. fprintf(stderr, "%s: wrong argument\n", arg);
  346. return 0;
  347. }
  348. i++;
  349. }
  350. #ifndef BADVPN_USE_WINAPI
  351. else if (!strcmp(arg, "--syslog-facility")) {
  352. if (1 >= argc - i) {
  353. fprintf(stderr, "%s: requires an argument\n", arg);
  354. return 0;
  355. }
  356. options.logger_syslog_facility = argv[i + 1];
  357. i++;
  358. }
  359. else if (!strcmp(arg, "--syslog-ident")) {
  360. if (1 >= argc - i) {
  361. fprintf(stderr, "%s: requires an argument\n", arg);
  362. return 0;
  363. }
  364. options.logger_syslog_ident = argv[i + 1];
  365. i++;
  366. }
  367. #endif
  368. else if (!strcmp(arg, "--loglevel")) {
  369. if (1 >= argc - i) {
  370. fprintf(stderr, "%s: requires an argument\n", arg);
  371. return 0;
  372. }
  373. if ((options.loglevel = parse_loglevel(argv[i + 1])) < 0) {
  374. fprintf(stderr, "%s: wrong argument\n", arg);
  375. return 0;
  376. }
  377. i++;
  378. }
  379. else if (!strcmp(arg, "--channel-loglevel")) {
  380. if (2 >= argc - i) {
  381. fprintf(stderr, "%s: requires two arguments\n", arg);
  382. return 0;
  383. }
  384. int channel = BLogGlobal_GetChannelByName(argv[i + 1]);
  385. if (channel < 0) {
  386. fprintf(stderr, "%s: wrong channel argument\n", arg);
  387. return 0;
  388. }
  389. int loglevel = parse_loglevel(argv[i + 2]);
  390. if (loglevel < 0) {
  391. fprintf(stderr, "%s: wrong loglevel argument\n", arg);
  392. return 0;
  393. }
  394. options.loglevels[channel] = loglevel;
  395. i += 2;
  396. }
  397. else if (!strcmp(arg, "--listen-addr")) {
  398. if (1 >= argc - i) {
  399. fprintf(stderr, "%s: requires an argument\n", arg);
  400. return 0;
  401. }
  402. if (options.num_listen_addrs == MAX_LISTEN_ADDRS) {
  403. fprintf(stderr, "%s: too many\n", arg);
  404. return 0;
  405. }
  406. options.listen_addrs[options.num_listen_addrs] = argv[i + 1];
  407. options.num_listen_addrs++;
  408. i++;
  409. }
  410. else if (!strcmp(arg, "--udp-mtu")) {
  411. if (1 >= argc - i) {
  412. fprintf(stderr, "%s: requires an argument\n", arg);
  413. return 0;
  414. }
  415. if ((options.udp_mtu = atoi(argv[i + 1])) < 0) {
  416. fprintf(stderr, "%s: wrong argument\n", arg);
  417. return 0;
  418. }
  419. i++;
  420. }
  421. else if (!strcmp(arg, "--max-clients")) {
  422. if (1 >= argc - i) {
  423. fprintf(stderr, "%s: requires an argument\n", arg);
  424. return 0;
  425. }
  426. if ((options.max_clients = atoi(argv[i + 1])) <= 0) {
  427. fprintf(stderr, "%s: wrong argument\n", arg);
  428. return 0;
  429. }
  430. i++;
  431. }
  432. else if (!strcmp(arg, "--max-connections-for-client")) {
  433. if (1 >= argc - i) {
  434. fprintf(stderr, "%s: requires an argument\n", arg);
  435. return 0;
  436. }
  437. if ((options.max_connections_for_client = atoi(argv[i + 1])) <= 0) {
  438. fprintf(stderr, "%s: wrong argument\n", arg);
  439. return 0;
  440. }
  441. i++;
  442. }
  443. else if (!strcmp(arg, "--client-socket-sndbuf")) {
  444. if (1 >= argc - i) {
  445. fprintf(stderr, "%s: requires an argument\n", arg);
  446. return 0;
  447. }
  448. if ((options.client_socket_sndbuf = atoi(argv[i + 1])) < 0) {
  449. fprintf(stderr, "%s: wrong argument\n", arg);
  450. return 0;
  451. }
  452. i++;
  453. }
  454. else {
  455. fprintf(stderr, "unknown option: %s\n", arg);
  456. return 0;
  457. }
  458. }
  459. if (options.help || options.version) {
  460. return 1;
  461. }
  462. return 1;
  463. }
  464. int process_arguments (void)
  465. {
  466. // resolve listen addresses
  467. num_listen_addrs = 0;
  468. while (num_listen_addrs < options.num_listen_addrs) {
  469. if (!BAddr_Parse(&listen_addrs[num_listen_addrs], options.listen_addrs[num_listen_addrs], NULL, 0)) {
  470. BLog(BLOG_ERROR, "listen addr: BAddr_Parse failed");
  471. return 0;
  472. }
  473. num_listen_addrs++;
  474. }
  475. return 1;
  476. }
  477. void signal_handler (void *unused)
  478. {
  479. BLog(BLOG_NOTICE, "termination requested");
  480. // exit event loop
  481. BReactor_Quit(&ss, 1);
  482. }
  483. void listener_handler (BListener *listener)
  484. {
  485. if (num_clients == options.max_clients) {
  486. BLog(BLOG_ERROR, "maximum number of clients reached");
  487. goto fail0;
  488. }
  489. // allocate structure
  490. struct client *client = malloc(sizeof(*client));
  491. if (!client) {
  492. BLog(BLOG_ERROR, "malloc failed");
  493. goto fail0;
  494. }
  495. // accept client
  496. if (!BConnection_Init(&client->con, BCONNECTION_SOURCE_LISTENER(listener, &client->addr), &ss, client, (BConnection_handler)client_connection_handler)) {
  497. BLog(BLOG_ERROR, "BConnection_Init failed");
  498. goto fail1;
  499. }
  500. // limit socket send buffer, else our scheduling is pointless
  501. if (options.client_socket_sndbuf > 0) {
  502. if (!BConnection_SetSendBuffer(&client->con, options.client_socket_sndbuf)) {
  503. BLog(BLOG_WARNING, "BConnection_SetSendBuffer failed");
  504. }
  505. }
  506. // init connection interfaces
  507. BConnection_SendAsync_Init(&client->con);
  508. BConnection_RecvAsync_Init(&client->con);
  509. // init disconnect timer
  510. BTimer_Init(&client->disconnect_timer, CLIENT_DISCONNECT_TIMEOUT, (BTimer_handler)client_disconnect_timer_handler, client);
  511. BReactor_SetTimer(&ss, &client->disconnect_timer);
  512. // init recv interface
  513. PacketPassInterface_Init(&client->recv_if, udpgw_mtu, (PacketPassInterface_handler_send)client_recv_if_handler_send, client, BReactor_PendingGroup(&ss));
  514. // init recv decoder
  515. if (!PacketProtoDecoder_Init(&client->recv_decoder, BConnection_RecvAsync_GetIf(&client->con), &client->recv_if, BReactor_PendingGroup(&ss), client,
  516. (PacketProtoDecoder_handler_error)client_decoder_handler_error
  517. )) {
  518. BLog(BLOG_ERROR, "PacketProtoDecoder_Init failed");
  519. goto fail2;
  520. }
  521. // init send sender
  522. PacketStreamSender_Init(&client->send_sender, BConnection_SendAsync_GetIf(&client->con), pp_mtu, BReactor_PendingGroup(&ss));
  523. // init send queue
  524. if (!PacketPassFairQueue_Init(&client->send_queue, PacketStreamSender_GetInput(&client->send_sender), BReactor_PendingGroup(&ss), 0, 1)) {
  525. BLog(BLOG_ERROR, "PacketPassFairQueue_Init failed");
  526. goto fail3;
  527. }
  528. // init connections tree
  529. BAVL_Init(&client->connections_tree, OFFSET_DIFF(struct connection, conid, connections_tree_node), (BAVL_comparator)uint16_comparator, NULL);
  530. // init connections list
  531. LinkedList1_Init(&client->connections_list);
  532. // set zero connections
  533. client->num_connections = 0;
  534. // init closing connections list
  535. LinkedList1_Init(&client->closing_connections_list);
  536. // insert to clients list
  537. LinkedList1_Append(&clients_list, &client->clients_list_node);
  538. num_clients++;
  539. client_log(client, BLOG_INFO, "connected");
  540. return;
  541. fail3:
  542. PacketStreamSender_Free(&client->send_sender);
  543. PacketProtoDecoder_Free(&client->recv_decoder);
  544. fail2:
  545. PacketPassInterface_Free(&client->recv_if);
  546. BReactor_RemoveTimer(&ss, &client->disconnect_timer);
  547. BConnection_RecvAsync_Free(&client->con);
  548. BConnection_SendAsync_Free(&client->con);
  549. BConnection_Free(&client->con);
  550. fail1:
  551. free(client);
  552. fail0:
  553. return;
  554. }
  555. void client_free (struct client *client)
  556. {
  557. // allow freeing send queue flows
  558. PacketPassFairQueue_PrepareFree(&client->send_queue);
  559. // free connections
  560. while (!LinkedList1_IsEmpty(&client->connections_list)) {
  561. struct connection *con = UPPER_OBJECT(LinkedList1_GetFirst(&client->connections_list), struct connection, connections_list_node);
  562. connection_free(con);
  563. }
  564. // free closing connections
  565. while (!LinkedList1_IsEmpty(&client->closing_connections_list)) {
  566. struct connection *con = UPPER_OBJECT(LinkedList1_GetFirst(&client->closing_connections_list), struct connection, closing_connections_list_node);
  567. connection_free(con);
  568. }
  569. // remove from clients list
  570. LinkedList1_Remove(&clients_list, &client->clients_list_node);
  571. num_clients--;
  572. // free send queue
  573. PacketPassFairQueue_Free(&client->send_queue);
  574. // free send sender
  575. PacketStreamSender_Free(&client->send_sender);
  576. // free recv decoder
  577. PacketProtoDecoder_Free(&client->recv_decoder);
  578. // free recv interface
  579. PacketPassInterface_Free(&client->recv_if);
  580. // free disconnect timer
  581. BReactor_RemoveTimer(&ss, &client->disconnect_timer);
  582. // free connection interfaces
  583. BConnection_RecvAsync_Free(&client->con);
  584. BConnection_SendAsync_Free(&client->con);
  585. // free connection
  586. BConnection_Free(&client->con);
  587. // free structure
  588. free(client);
  589. }
  590. void client_logfunc (struct client *client)
  591. {
  592. char addr[BADDR_MAX_PRINT_LEN];
  593. BAddr_Print(&client->addr, addr);
  594. BLog_Append("client (%s): ", addr);
  595. }
  596. void client_log (struct client *client, int level, const char *fmt, ...)
  597. {
  598. va_list vl;
  599. va_start(vl, fmt);
  600. BLog_LogViaFuncVarArg((BLog_logfunc)client_logfunc, client, BLOG_CURRENT_CHANNEL, level, fmt, vl);
  601. va_end(vl);
  602. }
  603. void client_disconnect_timer_handler (struct client *client)
  604. {
  605. client_log(client, BLOG_INFO, "timed out, disconnecting");
  606. // free client
  607. client_free(client);
  608. }
  609. void client_connection_handler (struct client *client, int event)
  610. {
  611. if (event == BCONNECTION_EVENT_RECVCLOSED) {
  612. client_log(client, BLOG_INFO, "client closed");
  613. } else {
  614. client_log(client, BLOG_INFO, "client error");
  615. }
  616. // free client
  617. client_free(client);
  618. }
  619. void client_decoder_handler_error (struct client *client)
  620. {
  621. client_log(client, BLOG_ERROR, "decoder error");
  622. // free client
  623. client_free(client);
  624. }
  625. void client_recv_if_handler_send (struct client *client, uint8_t *data, int data_len)
  626. {
  627. ASSERT(data_len >= 0)
  628. ASSERT(data_len <= udpgw_mtu)
  629. // accept packet
  630. PacketPassInterface_Done(&client->recv_if);
  631. // parse header
  632. if (data_len < sizeof(struct udpgw_header)) {
  633. client_log(client, BLOG_ERROR, "missing header");
  634. return;
  635. }
  636. struct udpgw_header *header = (struct udpgw_header *)data;
  637. data += sizeof(*header);
  638. data_len -= sizeof(*header);
  639. uint8_t flags = ltoh8(header->flags);
  640. uint16_t conid = ltoh16(header->conid);
  641. // reset disconnect timer
  642. BReactor_SetTimer(&ss, &client->disconnect_timer);
  643. // if this is keepalive, ignore any payload
  644. if ((flags & UDPGW_CLIENT_FLAG_KEEPALIVE)) {
  645. client_log(client, BLOG_DEBUG, "received keepalive");
  646. return;
  647. }
  648. // check payload length
  649. if (data_len > options.udp_mtu) {
  650. client_log(client, BLOG_ERROR, "too much data");
  651. return;
  652. }
  653. // find connection
  654. struct connection *con = find_connection(client, conid);
  655. ASSERT(!con || !con->closing)
  656. // if connection exists, close it if needed
  657. if (con && ((flags & UDPGW_CLIENT_FLAG_REBIND) || con->addr.ipv4.ip != header->addr_ip || con->addr.ipv4.port != header->addr_port)) {
  658. connection_log(con, BLOG_DEBUG, "close old");
  659. connection_close(con);
  660. con = NULL;
  661. }
  662. // if connection doesn't exists, create it
  663. if (!con) {
  664. // check number of connections
  665. if (client->num_connections == options.max_connections_for_client) {
  666. // close least recently used connection
  667. con = UPPER_OBJECT(LinkedList1_GetFirst(&client->connections_list), struct connection, connections_list_node);
  668. connection_close(con);
  669. }
  670. // read address
  671. BAddr addr;
  672. BAddr_InitIPv4(&addr, header->addr_ip, header->addr_port);
  673. // create new connection
  674. connection_init(client, conid, addr, data, data_len);
  675. } else {
  676. // submit packet to existing connection
  677. connection_send_to_udp(con, data, data_len);
  678. }
  679. }
  680. void connection_init (struct client *client, uint16_t conid, BAddr addr, const uint8_t *data, int data_len)
  681. {
  682. ASSERT(client->num_connections < options.max_connections_for_client)
  683. ASSERT(!find_connection(client, conid))
  684. BAddr_Assert(&addr);
  685. ASSERT(addr.type == BADDR_TYPE_IPV4)
  686. ASSERT(data_len >= 0)
  687. ASSERT(data_len <= options.udp_mtu)
  688. // allocate structure
  689. struct connection *con = malloc(sizeof(*con));
  690. if (!con) {
  691. client_log(client, BLOG_ERROR, "malloc failed");
  692. goto fail0;
  693. }
  694. // init arguments
  695. con->client = client;
  696. con->conid = conid;
  697. con->addr = addr;
  698. con->first_data = data;
  699. con->first_data_len = data_len;
  700. // set not closing
  701. con->closing = 0;
  702. // init first job
  703. BPending_Init(&con->first_job, BReactor_PendingGroup(&ss), (BPending_handler)connection_first_job_handler, con);
  704. BPending_Set(&con->first_job);
  705. // init send queue flow
  706. PacketPassFairQueueFlow_Init(&con->send_qflow, &client->send_queue);
  707. // init send PacketProtoFlow
  708. if (!PacketProtoFlow_Init(&con->send_ppflow, udpgw_mtu, CONNECTION_CLIENT_BUFFER_SIZE, PacketPassFairQueueFlow_GetInput(&con->send_qflow), BReactor_PendingGroup(&ss))) {
  709. client_log(client, BLOG_ERROR, "PacketProtoFlow_Init failed");
  710. goto fail1;
  711. }
  712. con->send_if = PacketProtoFlow_GetInput(&con->send_ppflow);
  713. // init UDP dgram
  714. if (!BDatagram_Init(&con->udp_dgram, addr.type, &ss, con, (BDatagram_handler)connection_dgram_handler_event)) {
  715. client_log(client, BLOG_ERROR, "BDatagram_Init failed");
  716. goto fail2;
  717. }
  718. // set UDP dgram send address
  719. BIPAddr ipaddr;
  720. BIPAddr_InitInvalid(&ipaddr);
  721. BDatagram_SetSendAddrs(&con->udp_dgram, addr, ipaddr);
  722. // init UDP dgram interfaces
  723. BDatagram_SendAsync_Init(&con->udp_dgram, options.udp_mtu);
  724. BDatagram_RecvAsync_Init(&con->udp_dgram, options.udp_mtu);
  725. // init UDP writer
  726. BufferWriter_Init(&con->udp_send_writer, options.udp_mtu, BReactor_PendingGroup(&ss));
  727. // init UDP buffer
  728. if (!PacketBuffer_Init(&con->udp_send_buffer, BufferWriter_GetOutput(&con->udp_send_writer), BDatagram_SendAsync_GetIf(&con->udp_dgram), CONNECTION_UDP_BUFFER_SIZE, BReactor_PendingGroup(&ss))) {
  729. client_log(client, BLOG_ERROR, "PacketBuffer_Init failed");
  730. goto fail4;
  731. }
  732. // init UDP recv interface
  733. PacketPassInterface_Init(&con->udp_recv_if, options.udp_mtu, (PacketPassInterface_handler_send)connection_udp_recv_if_handler_send, con, BReactor_PendingGroup(&ss));
  734. // init UDP recv buffer
  735. if (!SinglePacketBuffer_Init(&con->udp_recv_buffer, BDatagram_RecvAsync_GetIf(&con->udp_dgram), &con->udp_recv_if, BReactor_PendingGroup(&ss))) {
  736. client_log(client, BLOG_ERROR, "SinglePacketBuffer_Init failed");
  737. goto fail5;
  738. }
  739. // insert to client's connections tree
  740. ASSERT_EXECUTE(BAVL_Insert(&client->connections_tree, &con->connections_tree_node, NULL))
  741. // insert to client's connections list
  742. LinkedList1_Append(&client->connections_list, &con->connections_list_node);
  743. // increment number of connections
  744. client->num_connections++;
  745. connection_log(con, BLOG_DEBUG, "initialized");
  746. return;
  747. fail5:
  748. PacketPassInterface_Free(&con->udp_recv_if);
  749. PacketBuffer_Free(&con->udp_send_buffer);
  750. fail4:
  751. BufferWriter_Free(&con->udp_send_writer);
  752. BDatagram_RecvAsync_Free(&con->udp_dgram);
  753. BDatagram_SendAsync_Free(&con->udp_dgram);
  754. BDatagram_Free(&con->udp_dgram);
  755. fail2:
  756. PacketProtoFlow_Free(&con->send_ppflow);
  757. fail1:
  758. PacketPassFairQueueFlow_Free(&con->send_qflow);
  759. BPending_Free(&con->first_job);
  760. free(con);
  761. fail0:
  762. return;
  763. }
  764. void connection_free (struct connection *con)
  765. {
  766. struct client *client = con->client;
  767. PacketPassFairQueueFlow_AssertFree(&con->send_qflow);
  768. if (con->closing) {
  769. // remove from client's closing connections list
  770. LinkedList1_Remove(&client->closing_connections_list, &con->closing_connections_list_node);
  771. } else {
  772. // decrement number of connections
  773. client->num_connections--;
  774. // remove from client's connections list
  775. LinkedList1_Remove(&client->connections_list, &con->connections_list_node);
  776. // remove from client's connections tree
  777. BAVL_Remove(&client->connections_tree, &con->connections_tree_node);
  778. // free UDP
  779. connection_free_udp(con);
  780. }
  781. // free send PacketProtoFlow
  782. PacketProtoFlow_Free(&con->send_ppflow);
  783. // free send queue flow
  784. PacketPassFairQueueFlow_Free(&con->send_qflow);
  785. // free first job
  786. BPending_Free(&con->first_job);
  787. // free structure
  788. free(con);
  789. }
  790. void connection_logfunc (struct connection *con)
  791. {
  792. client_logfunc(con->client);
  793. if (con->closing) {
  794. BLog_Append("old connection %"PRIu16": ", con->conid);
  795. } else {
  796. BLog_Append("connection %"PRIu16": ", con->conid);
  797. }
  798. }
  799. void connection_log (struct connection *con, int level, const char *fmt, ...)
  800. {
  801. va_list vl;
  802. va_start(vl, fmt);
  803. BLog_LogViaFuncVarArg((BLog_logfunc)connection_logfunc, con, BLOG_CURRENT_CHANNEL, level, fmt, vl);
  804. va_end(vl);
  805. }
  806. void connection_free_udp (struct connection *con)
  807. {
  808. // free UDP receive buffer
  809. SinglePacketBuffer_Free(&con->udp_recv_buffer);
  810. // free UDP receive interface
  811. PacketPassInterface_Free(&con->udp_recv_if);
  812. // free UDP buffer
  813. PacketBuffer_Free(&con->udp_send_buffer);
  814. // free UDP writer
  815. BufferWriter_Free(&con->udp_send_writer);
  816. // free UDP dgram interfaces
  817. BDatagram_RecvAsync_Free(&con->udp_dgram);
  818. BDatagram_SendAsync_Free(&con->udp_dgram);
  819. // free UDP dgram
  820. BDatagram_Free(&con->udp_dgram);
  821. }
  822. void connection_first_job_handler (struct connection *con)
  823. {
  824. ASSERT(!con->closing)
  825. connection_send_to_udp(con, con->first_data, con->first_data_len);
  826. }
  827. int connection_send_to_client (struct connection *con, uint8_t flags, const uint8_t *data, int data_len)
  828. {
  829. ASSERT(data_len >= 0)
  830. ASSERT(data_len <= options.udp_mtu)
  831. // get buffer location
  832. uint8_t *out;
  833. if (!BufferWriter_StartPacket(con->send_if, &out)) {
  834. connection_log(con, BLOG_ERROR, "out of client buffer");
  835. return 0;
  836. }
  837. // write header
  838. struct udpgw_header *header = (struct udpgw_header *)out;
  839. header->flags = htol8(flags);
  840. header->conid = htol16(con->conid);
  841. header->addr_ip = con->addr.ipv4.ip;
  842. header->addr_port = con->addr.ipv4.port;
  843. // write message
  844. memcpy(out + sizeof(*header), data, data_len);
  845. // submit written message
  846. BufferWriter_EndPacket(con->send_if, sizeof(*header) + data_len);
  847. return 1;
  848. }
  849. int connection_send_to_udp (struct connection *con, const uint8_t *data, int data_len)
  850. {
  851. struct client *client = con->client;
  852. ASSERT(!con->closing)
  853. ASSERT(data_len >= 0)
  854. ASSERT(data_len <= options.udp_mtu)
  855. connection_log(con, BLOG_DEBUG, "from client %d bytes", data_len);
  856. // move connection to front
  857. LinkedList1_Remove(&client->connections_list, &con->connections_list_node);
  858. LinkedList1_Append(&client->connections_list, &con->connections_list_node);
  859. // get buffer location
  860. uint8_t *out;
  861. if (!BufferWriter_StartPacket(&con->udp_send_writer, &out)) {
  862. connection_log(con, BLOG_ERROR, "out of UDP buffer");
  863. return 0;
  864. }
  865. // write message
  866. memcpy(out, data, data_len);
  867. // submit written message
  868. BufferWriter_EndPacket(&con->udp_send_writer, data_len);
  869. return 1;
  870. }
  871. void connection_close (struct connection *con)
  872. {
  873. struct client *client = con->client;
  874. ASSERT(!con->closing)
  875. // if possible, free connection immediately
  876. if (!PacketPassFairQueueFlow_IsBusy(&con->send_qflow)) {
  877. connection_free(con);
  878. return;
  879. }
  880. connection_log(con, BLOG_DEBUG, "closing later");
  881. // decrement number of connections
  882. client->num_connections--;
  883. // remove from client's connections list
  884. LinkedList1_Remove(&client->connections_list, &con->connections_list_node);
  885. // remove from client's connections tree
  886. BAVL_Remove(&client->connections_tree, &con->connections_tree_node);
  887. // free UDP
  888. connection_free_udp(con);
  889. // insert to client's closing connections list
  890. LinkedList1_Append(&client->closing_connections_list, &con->closing_connections_list_node);
  891. // set busy handler
  892. PacketPassFairQueueFlow_SetBusyHandler(&con->send_qflow, (PacketPassFairQueue_handler_busy)connection_send_qflow_busy_handler, con);
  893. // unset first job
  894. BPending_Unset(&con->first_job);
  895. // set closing
  896. con->closing = 1;
  897. }
  898. void connection_send_qflow_busy_handler (struct connection *con)
  899. {
  900. ASSERT(con->closing)
  901. PacketPassFairQueueFlow_AssertFree(&con->send_qflow);
  902. connection_log(con, BLOG_DEBUG, "closing finally");
  903. // free connection
  904. connection_free(con);
  905. }
  906. void connection_dgram_handler_event (struct connection *con, int event)
  907. {
  908. ASSERT(!con->closing)
  909. connection_log(con, BLOG_INFO, "UDP error");
  910. // close connection
  911. connection_close(con);
  912. }
  913. void connection_udp_recv_if_handler_send (struct connection *con, uint8_t *data, int data_len)
  914. {
  915. struct client *client = con->client;
  916. ASSERT(!con->closing)
  917. ASSERT(data_len >= 0)
  918. ASSERT(data_len <= options.udp_mtu)
  919. connection_log(con, BLOG_DEBUG, "from UDP %d bytes", data_len);
  920. // move connection to front
  921. LinkedList1_Remove(&client->connections_list, &con->connections_list_node);
  922. LinkedList1_Append(&client->connections_list, &con->connections_list_node);
  923. // accept packet
  924. PacketPassInterface_Done(&con->udp_recv_if);
  925. // send packet to client
  926. connection_send_to_client(con, 0, data, data_len);
  927. }
  928. struct connection * find_connection (struct client *client, uint16_t conid)
  929. {
  930. BAVLNode *tree_node = BAVL_LookupExact(&client->connections_tree, &conid);
  931. if (!tree_node) {
  932. return NULL;
  933. }
  934. struct connection *con = UPPER_OBJECT(tree_node, struct connection, connections_tree_node);
  935. ASSERT(con->conid == conid)
  936. ASSERT(!con->closing)
  937. return con;
  938. }
  939. int uint16_comparator (void *unused, uint16_t *v1, uint16_t *v2)
  940. {
  941. if (*v1 < *v2) {
  942. return -1;
  943. }
  944. if (*v1 > *v2) {
  945. return 1;
  946. }
  947. return 0;
  948. }