server.c 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965
  1. /**
  2. * @file server.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. /*
  23. NOTE:
  24. This program works with I/O inside the BPending job environment.
  25. A consequence of this is that in response to an input, we can't
  26. directly do any output, but instead have to schedule outputs.
  27. Because all the buffers used (e.g. client control buffers and peer flows)
  28. are based on flow components, it is impossible to directly write two or more
  29. packets to a buffer.
  30. To, for instance, send two packets to a buffer, we have to first schedule
  31. writing the second packet (using BPending), then send the first one.
  32. */
  33. #include <inttypes.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #include <stddef.h>
  37. #include <stdarg.h>
  38. // NSPR and NSS
  39. #include <prinit.h>
  40. #include <prio.h>
  41. #include <prerror.h>
  42. #include <prtypes.h>
  43. #include <nss.h>
  44. #include <ssl.h>
  45. #include <cert.h>
  46. #include <keyhi.h>
  47. #include <secasn1.h>
  48. // BadVPN
  49. #include <misc/version.h>
  50. #include <misc/debug.h>
  51. #include <misc/offset.h>
  52. #include <misc/nsskey.h>
  53. #include <misc/byteorder.h>
  54. #include <misc/loglevel.h>
  55. #include <misc/loggers_string.h>
  56. #include <predicate/BPredicate.h>
  57. #include <base/BLog.h>
  58. #include <system/BSignal.h>
  59. #include <system/BTime.h>
  60. #include <base/DebugObject.h>
  61. #include <system/BAddr.h>
  62. #include <system/Listener.h>
  63. #include <security/BRandom.h>
  64. #include <nspr_support/DummyPRFileDesc.h>
  65. #ifndef BADVPN_USE_WINAPI
  66. #include <system/BLog_syslog.h>
  67. #endif
  68. #include <server/server.h>
  69. #include <generated/blog_channel_server.h>
  70. #define COMPONENT_SOURCE 1
  71. #define COMPONENT_SINK 2
  72. #define COMPONENT_DECODER 3
  73. #define LOGGER_STDOUT 1
  74. #define LOGGER_SYSLOG 2
  75. // parsed command-line options
  76. struct {
  77. int help;
  78. int version;
  79. int logger;
  80. #ifndef BADVPN_USE_WINAPI
  81. char *logger_syslog_facility;
  82. char *logger_syslog_ident;
  83. #endif
  84. int loglevel;
  85. int loglevels[BLOG_NUM_CHANNELS];
  86. int ssl;
  87. char *nssdb;
  88. char *server_cert_name;
  89. char *listen_addrs[MAX_LISTEN_ADDRS];
  90. int num_listen_addrs;
  91. char *comm_predicate;
  92. char *relay_predicate;
  93. } options;
  94. // listen addresses
  95. BAddr listen_addrs[MAX_LISTEN_ADDRS];
  96. int num_listen_addrs;
  97. // communication predicate
  98. BPredicate comm_predicate;
  99. // communication predicate functions
  100. BPredicateFunction comm_predicate_func_p1name;
  101. BPredicateFunction comm_predicate_func_p2name;
  102. BPredicateFunction comm_predicate_func_p1addr;
  103. BPredicateFunction comm_predicate_func_p2addr;
  104. // variables when evaluating the predicate, adjusted before every evaluation
  105. const char *comm_predicate_p1name;
  106. const char *comm_predicate_p2name;
  107. BIPAddr comm_predicate_p1addr;
  108. BIPAddr comm_predicate_p2addr;
  109. // relay predicate
  110. BPredicate relay_predicate;
  111. // gateway predicate functions
  112. BPredicateFunction relay_predicate_func_pname;
  113. BPredicateFunction relay_predicate_func_rname;
  114. BPredicateFunction relay_predicate_func_paddr;
  115. BPredicateFunction relay_predicate_func_raddr;
  116. // variables when evaluating the comm_predicate, adjusted before every evaluation
  117. const char *relay_predicate_pname;
  118. const char *relay_predicate_rname;
  119. BIPAddr relay_predicate_paddr;
  120. BIPAddr relay_predicate_raddr;
  121. // i/o system
  122. BReactor ss;
  123. // server certificate if using SSL
  124. CERTCertificate *server_cert;
  125. // server private key if using SSL
  126. SECKEYPrivateKey *server_key;
  127. // model NSPR file descriptor to speed up client initialization
  128. PRFileDesc model_dprfd;
  129. PRFileDesc *model_prfd;
  130. // listeners
  131. Listener listeners[MAX_LISTEN_ADDRS];
  132. int num_listeners;
  133. // number of connected clients
  134. int clients_num;
  135. // ID assigned to last connected client
  136. peerid_t clients_nextid;
  137. // clients list
  138. LinkedList2 clients;
  139. // clients tree (by ID)
  140. BAVL clients_tree;
  141. // cleans everything up that can be cleaned in order to return
  142. // from the event loop and exit
  143. static void terminate (void);
  144. // prints help text to standard output
  145. static void print_help (const char *name);
  146. // prints program name and version to standard output
  147. static void print_version (void);
  148. // parses the command line
  149. static int parse_arguments (int argc, char *argv[]);
  150. // processes certain command line options
  151. static int process_arguments (void);
  152. // handler for program termination request
  153. static void signal_handler (void *unused);
  154. // listener socket handler, accepts new clients
  155. static void listener_handler (Listener *listener);
  156. // adds a client. The client structure must have the sock and addr members
  157. // already initialized.
  158. static void client_add (struct client_data *client);
  159. // removes a client
  160. static void client_remove (struct client_data *client);
  161. // job for notifying clients when a client is removed
  162. static void client_dying_job (struct client_data *client);
  163. // frees resources used by a client
  164. static void client_dealloc (struct client_data *client);
  165. // passes a message to the logger, prepending about the client
  166. static void client_log (struct client_data *client, int level, const char *fmt, ...);
  167. // client activity timer handler. Removes the client.
  168. static void client_disconnect_timer_handler (struct client_data *client);
  169. // drives cline SSL handshake
  170. static void client_try_handshake (struct client_data *client);
  171. // event handler for driving client SSL handshake
  172. static void client_handshake_read_handler (struct client_data *client, PRInt16 event);
  173. // initializes the I/O porition of the client
  174. static int client_init_io (struct client_data *client);
  175. // deallocates the I/O portion of the client. Must have no outgoing flows.
  176. static void client_dealloc_io (struct client_data *client);
  177. // handler for client I/O errors. Removes the client.
  178. static void client_error_handler (struct client_data *client, int component, int code);
  179. // provides a buffer for sending a control packet to the client
  180. static int client_start_control_packet (struct client_data *client, void **data, int len);
  181. // submits a packet written after client_start_control_packet
  182. static void client_end_control_packet (struct client_data *client, uint8_t id);
  183. // sends a newclient message to a client
  184. static int client_send_newclient (struct client_data *client, struct client_data *nc, int relay_server, int relay_client);
  185. // sends an endclient message to a client
  186. static int client_send_endclient (struct client_data *client, peerid_t end_id);
  187. // handler for packets received from the client
  188. static void client_input_handler_send (struct client_data *client, uint8_t *data, int data_len);
  189. // processes hello packets from clients
  190. static void process_packet_hello (struct client_data *client, uint8_t *data, int data_len);
  191. // processes outmsg packets from clients
  192. static void process_packet_outmsg (struct client_data *client, uint8_t *data, int data_len);
  193. // creates a peer flow
  194. static struct peer_flow * peer_flow_create (struct client_data *src_client, struct client_data *dest_client);
  195. // deallocates a peer flow
  196. static void peer_flow_dealloc (struct peer_flow *flow);
  197. // disconnects the source client from a peer flow
  198. static void peer_flow_disconnect (struct peer_flow *flow);
  199. // provides a buffer for sending a peer-to-peer packet
  200. static int peer_flow_start_packet (struct peer_flow *flow, void **data, int len);
  201. // submits a peer-to-peer packet written after peer_flow_start_packet
  202. static void peer_flow_end_packet (struct peer_flow *flow, uint8_t type);
  203. // handler called by the queue when a peer flow can be freed after its source has gone away
  204. static void peer_flow_handler_canremove (struct peer_flow *flow);
  205. // generates a client ID to be used for a newly connected client
  206. static peerid_t new_client_id (void);
  207. // finds a client by its ID
  208. static struct client_data * find_client_by_id (peerid_t id);
  209. // checks if two clients are allowed to communicate. May depend on the order
  210. // of the clients.
  211. static int clients_allowed (struct client_data *client1, struct client_data *client2);
  212. // communication predicate function p1name
  213. static int comm_predicate_func_p1name_cb (void *user, void **args);
  214. // communication predicate function p2name
  215. static int comm_predicate_func_p2name_cb (void *user, void **args);
  216. // communication predicate function p1addr
  217. static int comm_predicate_func_p1addr_cb (void *user, void **args);
  218. // communication predicate function p2addr
  219. static int comm_predicate_func_p2addr_cb (void *user, void **args);
  220. // checks if relay is allowed for a client through another client
  221. static int relay_allowed (struct client_data *client, struct client_data *relay);
  222. // relay predicate function pname
  223. static int relay_predicate_func_pname_cb (void *user, void **args);
  224. // relay predicate function rname
  225. static int relay_predicate_func_rname_cb (void *user, void **args);
  226. // relay predicate function paddr
  227. static int relay_predicate_func_paddr_cb (void *user, void **args);
  228. // relay predicate function raddr
  229. static int relay_predicate_func_raddr_cb (void *user, void **args);
  230. // comparator for peerid_t used in AVL tree
  231. static int peerid_comparator (void *unused, peerid_t *p1, peerid_t *p2);
  232. static int create_know (struct client_data *from, struct client_data *to, int relay_server, int relay_client);
  233. static void remove_know (struct peer_know *k);
  234. static void know_inform_job_handler (struct peer_know *k);
  235. static void uninform_know (struct peer_know *k);
  236. static void know_uninform_job_handler (struct peer_know *k);
  237. int main (int argc, char *argv[])
  238. {
  239. if (argc <= 0) {
  240. return 1;
  241. }
  242. // parse command-line arguments
  243. if (!parse_arguments(argc, argv)) {
  244. fprintf(stderr, "Failed to parse arguments\n");
  245. print_help(argv[0]);
  246. goto fail0;
  247. }
  248. // handle --help and --version
  249. if (options.help) {
  250. print_version();
  251. print_help(argv[0]);
  252. return 0;
  253. }
  254. if (options.version) {
  255. print_version();
  256. return 0;
  257. }
  258. // initialize logger
  259. switch (options.logger) {
  260. case LOGGER_STDOUT:
  261. BLog_InitStdout();
  262. break;
  263. #ifndef BADVPN_USE_WINAPI
  264. case LOGGER_SYSLOG:
  265. if (!BLog_InitSyslog(options.logger_syslog_ident, options.logger_syslog_facility)) {
  266. fprintf(stderr, "Failed to initialize syslog logger\n");
  267. goto fail0;
  268. }
  269. break;
  270. #endif
  271. default:
  272. ASSERT(0);
  273. }
  274. // configure logger channels
  275. for (int i = 0; i < BLOG_NUM_CHANNELS; i++) {
  276. if (options.loglevels[i] >= 0) {
  277. BLog_SetChannelLoglevel(i, options.loglevels[i]);
  278. }
  279. else if (options.loglevel >= 0) {
  280. BLog_SetChannelLoglevel(i, options.loglevel);
  281. }
  282. }
  283. BLog(BLOG_NOTICE, "initializing "GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION);
  284. // initialize sockets
  285. if (BSocket_GlobalInit() < 0) {
  286. BLog(BLOG_ERROR, "BSocket_GlobalInit failed");
  287. goto fail1;
  288. }
  289. // process arguments
  290. if (!process_arguments()) {
  291. BLog(BLOG_ERROR, "Failed to process arguments");
  292. goto fail1;
  293. }
  294. // init communication predicate
  295. if (options.comm_predicate) {
  296. // init predicate
  297. if (!BPredicate_Init(&comm_predicate, options.comm_predicate)) {
  298. BLog(BLOG_ERROR, "BPredicate_Init failed");
  299. goto fail1;
  300. }
  301. // init functions
  302. BPredicateFunction_Init(&comm_predicate_func_p1name, &comm_predicate, "p1name", (int []){PREDICATE_TYPE_STRING}, 1, comm_predicate_func_p1name_cb, NULL);
  303. BPredicateFunction_Init(&comm_predicate_func_p2name, &comm_predicate, "p2name", (int []){PREDICATE_TYPE_STRING}, 1, comm_predicate_func_p2name_cb, NULL);
  304. BPredicateFunction_Init(&comm_predicate_func_p1addr, &comm_predicate, "p1addr", (int []){PREDICATE_TYPE_STRING}, 1, comm_predicate_func_p1addr_cb, NULL);
  305. BPredicateFunction_Init(&comm_predicate_func_p2addr, &comm_predicate, "p2addr", (int []){PREDICATE_TYPE_STRING}, 1, comm_predicate_func_p2addr_cb, NULL);
  306. }
  307. // init relay predicate
  308. if (options.relay_predicate) {
  309. // init predicate
  310. if (!BPredicate_Init(&relay_predicate, options.relay_predicate)) {
  311. BLog(BLOG_ERROR, "BPredicate_Init failed");
  312. goto fail1_1;
  313. }
  314. // init functions
  315. BPredicateFunction_Init(&relay_predicate_func_pname, &relay_predicate, "pname", (int []){PREDICATE_TYPE_STRING}, 1, relay_predicate_func_pname_cb, NULL);
  316. BPredicateFunction_Init(&relay_predicate_func_rname, &relay_predicate, "rname", (int []){PREDICATE_TYPE_STRING}, 1, relay_predicate_func_rname_cb, NULL);
  317. BPredicateFunction_Init(&relay_predicate_func_paddr, &relay_predicate, "paddr", (int []){PREDICATE_TYPE_STRING}, 1, relay_predicate_func_paddr_cb, NULL);
  318. BPredicateFunction_Init(&relay_predicate_func_raddr, &relay_predicate, "raddr", (int []){PREDICATE_TYPE_STRING}, 1, relay_predicate_func_raddr_cb, NULL);
  319. }
  320. // init time
  321. BTime_Init();
  322. // initialize reactor
  323. if (!BReactor_Init(&ss)) {
  324. BLog(BLOG_ERROR, "BReactor_Init failed");
  325. goto fail2;
  326. }
  327. // setup signal handler
  328. if (!BSignal_Init(&ss, signal_handler, NULL)) {
  329. BLog(BLOG_ERROR, "BSignal_Init failed");
  330. goto fail2a;
  331. }
  332. if (options.ssl) {
  333. // initialize NSPR
  334. PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
  335. // initialize i/o layer types
  336. if (!DummyPRFileDesc_GlobalInit()) {
  337. BLog(BLOG_ERROR, "DummyPRFileDesc_GlobalInit failed");
  338. goto fail3;
  339. }
  340. if (!BSocketPRFileDesc_GlobalInit()) {
  341. BLog(BLOG_ERROR, "BSocketPRFileDesc_GlobalInit failed");
  342. goto fail3;
  343. }
  344. // initialize NSS
  345. if (NSS_Init(options.nssdb) != SECSuccess) {
  346. BLog(BLOG_ERROR, "NSS_Init failed (%d)", (int)PR_GetError());
  347. goto fail3;
  348. }
  349. if (NSS_SetDomesticPolicy() != SECSuccess) {
  350. BLog(BLOG_ERROR, "NSS_SetDomesticPolicy failed (%d)", (int)PR_GetError());
  351. goto fail4;
  352. }
  353. // initialize server cache
  354. if (SSL_ConfigServerSessionIDCache(0, 0, 0, NULL) != SECSuccess) {
  355. BLog(BLOG_ERROR, "SSL_ConfigServerSessionIDCache failed (%d)", (int)PR_GetError());
  356. goto fail4;
  357. }
  358. // open server certificate and private key
  359. if (!open_nss_cert_and_key(options.server_cert_name, &server_cert, &server_key)) {
  360. BLog(BLOG_ERROR, "Cannot open certificate and key");
  361. goto fail4a;
  362. }
  363. // initialize model SSL fd
  364. DummyPRFileDesc_Create(&model_dprfd);
  365. if (!(model_prfd = SSL_ImportFD(NULL, &model_dprfd))) {
  366. BLog(BLOG_ERROR, "SSL_ImportFD failed");
  367. ASSERT_FORCE(PR_Close(&model_dprfd) == PR_SUCCESS)
  368. goto fail5;
  369. }
  370. // set server certificate
  371. if (SSL_ConfigSecureServer(model_prfd, server_cert, server_key, NSS_FindCertKEAType(server_cert)) != SECSuccess) {
  372. BLog(BLOG_ERROR, "SSL_ConfigSecureServer failed");
  373. goto fail6;
  374. }
  375. }
  376. // initialize number of clients
  377. clients_num = 0;
  378. // first client ID will be zero
  379. clients_nextid = 0;
  380. // initialize clients linked list
  381. LinkedList2_Init(&clients);
  382. // initialize clients tree
  383. BAVL_Init(&clients_tree, OFFSET_DIFF(struct client_data, id, tree_node), (BAVL_comparator)peerid_comparator, NULL);
  384. // initialize listeners
  385. num_listeners = 0;
  386. while (num_listeners < num_listen_addrs) {
  387. if (!Listener_Init(&listeners[num_listeners], &ss, listen_addrs[num_listeners], (Listener_handler)listener_handler, &listeners[num_listeners])) {
  388. BLog(BLOG_ERROR, "Listener_Init failed");
  389. goto fail7;
  390. }
  391. num_listeners++;
  392. }
  393. // enter event loop
  394. BLog(BLOG_NOTICE, "entering event loop");
  395. BReactor_Exec(&ss);
  396. // free clients
  397. LinkedList2Node *node;
  398. while (node = LinkedList2_GetFirst(&clients)) {
  399. struct client_data *client = UPPER_OBJECT(node, struct client_data, list_node);
  400. // remove outgoing knows
  401. LinkedList2Node *node2;
  402. while (node2 = LinkedList2_GetFirst(&client->know_out_list)) {
  403. struct peer_know *k = UPPER_OBJECT(node2, struct peer_know, from_node);
  404. remove_know(k);
  405. }
  406. // remove incoming knows
  407. LinkedList2Node *node3;
  408. while (node3 = LinkedList2_GetFirst(&client->know_in_list)) {
  409. struct peer_know *k = UPPER_OBJECT(node3, struct peer_know, to_node);
  410. remove_know(k);
  411. }
  412. // remove outgoing flows
  413. LinkedList2Node *flow_node;
  414. while (flow_node = LinkedList2_GetFirst(&client->peer_out_flows_list)) {
  415. struct peer_flow *flow = UPPER_OBJECT(flow_node, struct peer_flow, src_list_node);
  416. ASSERT(flow->src_client == client)
  417. // allow freeing queue flows at dest
  418. PacketPassFairQueue_PrepareFree(&flow->dest_client->output_peers_fairqueue);
  419. // deallocate flow
  420. peer_flow_dealloc(flow);
  421. }
  422. // deallocate client
  423. client_dealloc(client);
  424. }
  425. fail7:
  426. while (num_listeners > 0) {
  427. num_listeners--;
  428. Listener_Free(&listeners[num_listeners]);
  429. }
  430. if (options.ssl) {
  431. fail6:
  432. ASSERT_FORCE(PR_Close(model_prfd) == PR_SUCCESS)
  433. fail5:
  434. CERT_DestroyCertificate(server_cert);
  435. SECKEY_DestroyPrivateKey(server_key);
  436. fail4a:
  437. ASSERT_FORCE(SSL_ShutdownServerSessionIDCache() == SECSuccess)
  438. fail4:
  439. ASSERT_FORCE(NSS_Shutdown() == SECSuccess)
  440. fail3:
  441. ASSERT_FORCE(PR_Cleanup() == PR_SUCCESS)
  442. PL_ArenaFinish();
  443. }
  444. BSignal_Finish();
  445. fail2a:
  446. BReactor_Free(&ss);
  447. fail2:
  448. if (options.relay_predicate) {
  449. BPredicateFunction_Free(&relay_predicate_func_raddr);
  450. BPredicateFunction_Free(&relay_predicate_func_paddr);
  451. BPredicateFunction_Free(&relay_predicate_func_rname);
  452. BPredicateFunction_Free(&relay_predicate_func_pname);
  453. BPredicate_Free(&relay_predicate);
  454. }
  455. fail1_1:
  456. if (options.comm_predicate) {
  457. BPredicateFunction_Free(&comm_predicate_func_p2addr);
  458. BPredicateFunction_Free(&comm_predicate_func_p1addr);
  459. BPredicateFunction_Free(&comm_predicate_func_p2name);
  460. BPredicateFunction_Free(&comm_predicate_func_p1name);
  461. BPredicate_Free(&comm_predicate);
  462. }
  463. fail1:
  464. BLog(BLOG_NOTICE, "exiting");
  465. BLog_Free();
  466. fail0:
  467. DebugObjectGlobal_Finish();
  468. return 1;
  469. }
  470. void terminate (void)
  471. {
  472. BLog(BLOG_NOTICE, "tearing down");
  473. // exit event loop
  474. BReactor_Quit(&ss, 0);
  475. }
  476. void print_help (const char *name)
  477. {
  478. printf(
  479. "Usage:\n"
  480. " %s\n"
  481. " [--help]\n"
  482. " [--version]\n"
  483. " [--logger <"LOGGERS_STRING">]\n"
  484. #ifndef BADVPN_USE_WINAPI
  485. " (logger=syslog?\n"
  486. " [--syslog-facility <string>]\n"
  487. " [--syslog-ident <string>]\n"
  488. " )\n"
  489. #endif
  490. " [--loglevel <0-5/none/error/warning/notice/info/debug>]\n"
  491. " [--channel-loglevel <channel-name> <0-5/none/error/warning/notice/info/debug>] ...\n"
  492. " [--listen-addr <addr>] ...\n"
  493. " [--ssl --nssdb <string> --server-cert-name <string>]\n"
  494. " [--comm-predicate <string>]\n"
  495. " [--relay-predicate <string>]\n"
  496. "Address format is a.b.c.d:port (IPv4) or [addr]:port (IPv6).\n",
  497. name
  498. );
  499. }
  500. void print_version (void)
  501. {
  502. printf(GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION"\n"GLOBAL_COPYRIGHT_NOTICE"\n");
  503. }
  504. int parse_arguments (int argc, char *argv[])
  505. {
  506. options.help = 0;
  507. options.version = 0;
  508. options.logger = LOGGER_STDOUT;
  509. #ifndef BADVPN_USE_WINAPI
  510. options.logger_syslog_facility = "daemon";
  511. options.logger_syslog_ident = argv[0];
  512. #endif
  513. options.loglevel = -1;
  514. for (int i = 0; i < BLOG_NUM_CHANNELS; i++) {
  515. options.loglevels[i] = -1;
  516. }
  517. options.ssl = 0;
  518. options.nssdb = NULL;
  519. options.server_cert_name = NULL;
  520. options.num_listen_addrs = 0;
  521. options.comm_predicate = NULL;
  522. options.relay_predicate = NULL;
  523. for (int i = 1; i < argc; i++) {
  524. char *arg = argv[i];
  525. if (!strcmp(arg, "--help")) {
  526. options.help = 1;
  527. }
  528. else if (!strcmp(arg, "--version")) {
  529. options.version = 1;
  530. }
  531. else if (!strcmp(arg, "--logger")) {
  532. if (i + 1 >= argc) {
  533. fprintf(stderr, "%s: requires an argument\n", arg);
  534. return 0;
  535. }
  536. char *arg2 = argv[i + 1];
  537. if (!strcmp(arg2, "stdout")) {
  538. options.logger = LOGGER_STDOUT;
  539. }
  540. #ifndef BADVPN_USE_WINAPI
  541. else if (!strcmp(arg2, "syslog")) {
  542. options.logger = LOGGER_SYSLOG;
  543. }
  544. #endif
  545. else {
  546. fprintf(stderr, "%s: wrong argument\n", arg);
  547. return 0;
  548. }
  549. i++;
  550. }
  551. #ifndef BADVPN_USE_WINAPI
  552. else if (!strcmp(arg, "--syslog-facility")) {
  553. if (i + 1 >= argc) {
  554. fprintf(stderr, "%s: requires an argument\n", arg);
  555. return 0;
  556. }
  557. options.logger_syslog_facility = argv[i + 1];
  558. i++;
  559. }
  560. else if (!strcmp(arg, "--syslog-ident")) {
  561. if (i + 1 >= argc) {
  562. fprintf(stderr, "%s: requires an argument\n", arg);
  563. return 0;
  564. }
  565. options.logger_syslog_ident = argv[i + 1];
  566. i++;
  567. }
  568. #endif
  569. else if (!strcmp(arg, "--loglevel")) {
  570. if (1 >= argc - i) {
  571. fprintf(stderr, "%s: requires an argument\n", arg);
  572. return 0;
  573. }
  574. if ((options.loglevel = parse_loglevel(argv[i + 1])) < 0) {
  575. fprintf(stderr, "%s: wrong argument\n", arg);
  576. return 0;
  577. }
  578. i++;
  579. }
  580. else if (!strcmp(arg, "--channel-loglevel")) {
  581. if (2 >= argc - i) {
  582. fprintf(stderr, "%s: requires two arguments\n", arg);
  583. return 0;
  584. }
  585. int channel = BLogGlobal_GetChannelByName(argv[i + 1]);
  586. if (channel < 0) {
  587. fprintf(stderr, "%s: wrong channel argument\n", arg);
  588. return 0;
  589. }
  590. int loglevel = parse_loglevel(argv[i + 2]);
  591. if (loglevel < 0) {
  592. fprintf(stderr, "%s: wrong loglevel argument\n", arg);
  593. return 0;
  594. }
  595. options.loglevels[channel] = loglevel;
  596. i += 2;
  597. }
  598. else if (!strcmp(arg, "--ssl")) {
  599. options.ssl = 1;
  600. }
  601. else if (!strcmp(arg, "--nssdb")) {
  602. if (1 >= argc - i) {
  603. fprintf(stderr, "%s: requires an argument\n", arg);
  604. return 0;
  605. }
  606. options.nssdb = argv[i + 1];
  607. i++;
  608. }
  609. else if (!strcmp(arg, "--server-cert-name")) {
  610. if (1 >= argc - i) {
  611. fprintf(stderr, "%s: requires an argument\n", arg);
  612. return 0;
  613. }
  614. options.server_cert_name = argv[i + 1];
  615. i++;
  616. }
  617. else if (!strcmp(arg, "--listen-addr")) {
  618. if (1 >= argc - i) {
  619. fprintf(stderr, "%s: requires an argument\n", arg);
  620. return 0;
  621. }
  622. if (options.num_listen_addrs == MAX_LISTEN_ADDRS) {
  623. fprintf(stderr, "%s: too many\n", arg);
  624. return 0;
  625. }
  626. options.listen_addrs[options.num_listen_addrs] = argv[i + 1];
  627. options.num_listen_addrs++;
  628. i++;
  629. }
  630. else if (!strcmp(arg, "--comm-predicate")) {
  631. if (1 >= argc - i) {
  632. fprintf(stderr, "%s: requires an argument\n", arg);
  633. return 0;
  634. }
  635. options.comm_predicate = argv[i + 1];
  636. i++;
  637. }
  638. else if (!strcmp(arg, "--relay-predicate")) {
  639. if (1 >= argc - i) {
  640. fprintf(stderr, "%s: requires an argument\n", arg);
  641. return 0;
  642. }
  643. options.relay_predicate = argv[i + 1];
  644. i++;
  645. }
  646. else {
  647. fprintf(stderr, "%s: unknown option\n", arg);
  648. return 0;
  649. }
  650. }
  651. if (options.help || options.version) {
  652. return 1;
  653. }
  654. if (!!options.nssdb != options.ssl) {
  655. fprintf(stderr, "--ssl and --nssdb must be used together\n");
  656. return 0;
  657. }
  658. if (!!options.server_cert_name != options.ssl) {
  659. fprintf(stderr, "--ssl and --server-cert-name must be used together\n");
  660. return 0;
  661. }
  662. return 1;
  663. }
  664. int process_arguments (void)
  665. {
  666. // resolve listen addresses
  667. num_listen_addrs = 0;
  668. while (num_listen_addrs < options.num_listen_addrs) {
  669. if (!BAddr_Parse(&listen_addrs[num_listen_addrs], options.listen_addrs[num_listen_addrs], NULL, 0)) {
  670. BLog(BLOG_ERROR, "listen addr: BAddr_Parse failed");
  671. return 0;
  672. }
  673. num_listen_addrs++;
  674. }
  675. return 1;
  676. }
  677. void signal_handler (void *unused)
  678. {
  679. BLog(BLOG_NOTICE, "termination requested");
  680. terminate();
  681. return;
  682. }
  683. void listener_handler (Listener *listener)
  684. {
  685. if (clients_num == MAX_CLIENTS) {
  686. BLog(BLOG_WARNING, "too many clients for new client");
  687. goto fail0;
  688. }
  689. // allocate the client structure
  690. struct client_data *client = malloc(sizeof(*client));
  691. if (!client) {
  692. BLog(BLOG_ERROR, "failed to allocate client");
  693. goto fail0;
  694. }
  695. // accept it
  696. if (!Listener_Accept(listener, &client->sock, &client->addr)) {
  697. BLog(BLOG_NOTICE, "Listener_Accept failed");
  698. goto fail1;
  699. }
  700. client_add(client);
  701. return;
  702. fail1:
  703. free(client);
  704. fail0:
  705. ;
  706. }
  707. void client_add (struct client_data *client)
  708. {
  709. ASSERT(clients_num < MAX_CLIENTS)
  710. // assign ID
  711. client->id = new_client_id();
  712. // set no common name
  713. client->common_name = NULL;
  714. // now client_log() works
  715. if (options.ssl) {
  716. // initialize SSL
  717. // create BSocket NSPR file descriptor
  718. BSocketPRFileDesc_Create(&client->bottom_prfd, &client->sock);
  719. // create SSL file descriptor from the socket's BSocketPRFileDesc
  720. if (!(client->ssl_prfd = SSL_ImportFD(model_prfd, &client->bottom_prfd))) {
  721. client_log(client, BLOG_ERROR, "SSL_ImportFD failed");
  722. ASSERT_FORCE(PR_Close(&client->bottom_prfd) == PR_SUCCESS)
  723. goto fail0;
  724. }
  725. // set server mode
  726. if (SSL_ResetHandshake(client->ssl_prfd, PR_TRUE) != SECSuccess) {
  727. client_log(client, BLOG_ERROR, "SSL_ResetHandshake failed");
  728. goto fail1;
  729. }
  730. // set require client certificate
  731. if (SSL_OptionSet(client->ssl_prfd, SSL_REQUEST_CERTIFICATE, PR_TRUE) != SECSuccess) {
  732. client_log(client, BLOG_ERROR, "SSL_OptionSet(SSL_REQUEST_CERTIFICATE) failed");
  733. goto fail1;
  734. }
  735. if (SSL_OptionSet(client->ssl_prfd, SSL_REQUIRE_CERTIFICATE, PR_TRUE) != SECSuccess) {
  736. client_log(client, BLOG_ERROR, "SSL_OptionSet(SSL_REQUIRE_CERTIFICATE) failed");
  737. goto fail1;
  738. }
  739. // initialize BPRFileDesc on SSL file descriptor
  740. BPRFileDesc_Init(&client->ssl_bprfd, client->ssl_prfd);
  741. } else {
  742. // initialize I/O
  743. if (!client_init_io(client)) {
  744. goto fail0;
  745. }
  746. }
  747. // start disconnect timer
  748. BTimer_Init(&client->disconnect_timer, CLIENT_NO_DATA_TIME_LIMIT, (BTimer_handler)client_disconnect_timer_handler, client);
  749. BReactor_SetTimer(&ss, &client->disconnect_timer);
  750. // link in
  751. clients_num++;
  752. LinkedList2_Append(&clients, &client->list_node);
  753. ASSERT_EXECUTE(BAVL_Insert(&clients_tree, &client->tree_node, NULL))
  754. // init knowledge lists
  755. LinkedList2_Init(&client->know_out_list);
  756. LinkedList2_Init(&client->know_in_list);
  757. // initialize peer flows from us list and tree (flows for sending messages to other clients)
  758. LinkedList2_Init(&client->peer_out_flows_list);
  759. BAVL_Init(&client->peer_out_flows_tree, OFFSET_DIFF(struct peer_flow, dest_client_id, src_tree_node), (BAVL_comparator)peerid_comparator, NULL);
  760. // init dying
  761. client->dying = 0;
  762. BPending_Init(&client->dying_job, BReactor_PendingGroup(&ss), (BPending_handler)client_dying_job, client);
  763. // set state
  764. client->initstatus = (options.ssl ? INITSTATUS_HANDSHAKE : INITSTATUS_WAITHELLO);
  765. client_log(client, BLOG_INFO, "initialized");
  766. // start I/O
  767. if (options.ssl) {
  768. // set read handler for driving handshake
  769. BPRFileDesc_AddEventHandler(&client->ssl_bprfd, PR_POLL_READ, (BPRFileDesc_handler)client_handshake_read_handler, client);
  770. // start handshake
  771. client_try_handshake(client);
  772. return;
  773. } else {
  774. return;
  775. }
  776. // cleanup on errors
  777. fail1:
  778. if (options.ssl) {
  779. ASSERT_FORCE(PR_Close(client->ssl_prfd) == PR_SUCCESS)
  780. }
  781. fail0:
  782. BSocket_Free(&client->sock);
  783. free(client);
  784. }
  785. void client_remove (struct client_data *client)
  786. {
  787. ASSERT(!client->dying)
  788. client_log(client, BLOG_NOTICE, "removing");
  789. // set dying to prevent sending this client anything
  790. client->dying = 1;
  791. // free I/O (including incoming flows)
  792. if (client->initstatus >= INITSTATUS_WAITHELLO) {
  793. client_dealloc_io(client);
  794. }
  795. // remove outgoing knows
  796. LinkedList2Node *node;
  797. while (node = LinkedList2_GetFirst(&client->know_out_list)) {
  798. struct peer_know *k = UPPER_OBJECT(node, struct peer_know, from_node);
  799. remove_know(k);
  800. }
  801. // remove outgoing flows
  802. while (node = LinkedList2_GetFirst(&client->peer_out_flows_list)) {
  803. struct peer_flow *flow = UPPER_OBJECT(node, struct peer_flow, src_list_node);
  804. ASSERT(flow->src_client == client)
  805. ASSERT(flow->dest_client->initstatus == INITSTATUS_COMPLETE && !flow->dest_client->dying)
  806. if (PacketPassFairQueueFlow_IsBusy(&flow->qflow)) {
  807. client_log(client, BLOG_DEBUG, "removing flow later");
  808. peer_flow_disconnect(flow);
  809. PacketPassFairQueueFlow_SetBusyHandler(&flow->qflow, (PacketPassFairQueue_handler_busy)peer_flow_handler_canremove, flow);
  810. } else {
  811. client_log(client, BLOG_DEBUG, "removing flow now");
  812. peer_flow_dealloc(flow);
  813. }
  814. }
  815. // schedule job to finish removal after clients are informed
  816. BPending_Set(&client->dying_job);
  817. // inform other clients that 'client' is no more
  818. LinkedList2Iterator it;
  819. LinkedList2Iterator_InitForward(&it, &client->know_in_list);
  820. while (node = LinkedList2Iterator_Next(&it)) {
  821. struct peer_know *k = UPPER_OBJECT(node, struct peer_know, to_node);
  822. uninform_know(k);
  823. }
  824. }
  825. void client_dying_job (struct client_data *client)
  826. {
  827. ASSERT(client->dying)
  828. ASSERT(LinkedList2_IsEmpty(&client->know_in_list))
  829. client_dealloc(client);
  830. return;
  831. }
  832. void client_dealloc (struct client_data *client)
  833. {
  834. ASSERT(LinkedList2_IsEmpty(&client->know_out_list))
  835. ASSERT(LinkedList2_IsEmpty(&client->know_in_list))
  836. ASSERT(LinkedList2_IsEmpty(&client->peer_out_flows_list))
  837. // free I/O
  838. if (client->initstatus >= INITSTATUS_WAITHELLO && !client->dying) {
  839. client_dealloc_io(client);
  840. }
  841. // free dying
  842. BPending_Free(&client->dying_job);
  843. // link out
  844. BAVL_Remove(&clients_tree, &client->tree_node);
  845. LinkedList2_Remove(&clients, &client->list_node);
  846. clients_num--;
  847. // stop disconnect timer
  848. BReactor_RemoveTimer(&ss, &client->disconnect_timer);
  849. // free SSL
  850. if (options.ssl) {
  851. // free BPRFileDesc
  852. BPRFileDesc_Free(&client->ssl_bprfd);
  853. // free SSL PRFD
  854. ASSERT_FORCE(PR_Close(client->ssl_prfd) == PR_SUCCESS)
  855. }
  856. // free common name
  857. if (client->common_name) {
  858. PORT_Free(client->common_name);
  859. }
  860. // free socket
  861. BSocket_Free(&client->sock);
  862. // free memory
  863. free(client);
  864. }
  865. void client_log (struct client_data *client, int level, const char *fmt, ...)
  866. {
  867. va_list vl;
  868. va_start(vl, fmt);
  869. char addr[BADDR_MAX_PRINT_LEN];
  870. BAddr_Print(&client->addr, addr);
  871. BLog_Append("client %d (%s)", (int)client->id, addr);
  872. if (client->common_name) {
  873. BLog_Append(" (%s)", client->common_name);
  874. }
  875. BLog_Append(": ");
  876. BLog_LogToChannelVarArg(BLOG_CURRENT_CHANNEL, level, fmt, vl);
  877. va_end(vl);
  878. }
  879. void client_disconnect_timer_handler (struct client_data *client)
  880. {
  881. ASSERT(!client->dying)
  882. client_log(client, BLOG_NOTICE, "timed out");
  883. client_remove(client);
  884. return;
  885. }
  886. void client_try_handshake (struct client_data *client)
  887. {
  888. ASSERT(client->initstatus == INITSTATUS_HANDSHAKE)
  889. ASSERT(!client->dying)
  890. // attempt handshake
  891. if (SSL_ForceHandshake(client->ssl_prfd) != SECSuccess) {
  892. PRErrorCode error = PR_GetError();
  893. if (error == PR_WOULD_BLOCK_ERROR) {
  894. // try again on read event
  895. BPRFileDesc_EnableEvent(&client->ssl_bprfd, PR_POLL_READ);
  896. return;
  897. }
  898. client_log(client, BLOG_NOTICE, "SSL_ForceHandshake failed (%d)", (int)error);
  899. goto fail0;
  900. }
  901. // remove read handler
  902. BPRFileDesc_RemoveEventHandler(&client->ssl_bprfd, PR_POLL_READ);
  903. // get client certificate
  904. CERTCertificate *cert = SSL_PeerCertificate(client->ssl_prfd);
  905. if (!cert) {
  906. client_log(client, BLOG_ERROR, "SSL_PeerCertificate failed");
  907. goto fail0;
  908. }
  909. // remember common name
  910. if (!(client->common_name = CERT_GetCommonName(&cert->subject))) {
  911. client_log(client, BLOG_NOTICE, "CERT_GetCommonName failed");
  912. goto fail1;
  913. }
  914. // store certificate
  915. SECItem der = cert->derCert;
  916. if (der.len > sizeof(client->cert)) {
  917. client_log(client, BLOG_NOTICE, "client certificate too big");
  918. goto fail1;
  919. }
  920. memcpy(client->cert, der.data, der.len);
  921. client->cert_len = der.len;
  922. PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  923. if (!arena) {
  924. client_log(client, BLOG_ERROR, "PORT_NewArena failed");
  925. goto fail1;
  926. }
  927. // encode certificate
  928. memset(&der, 0, sizeof(der));
  929. if (!SEC_ASN1EncodeItem(arena, &der, cert, SEC_ASN1_GET(CERT_CertificateTemplate))) {
  930. client_log(client, BLOG_ERROR, "SEC_ASN1EncodeItem failed");
  931. goto fail2;
  932. }
  933. // store re-encoded certificate (for compatibility with old clients)
  934. if (der.len > sizeof(client->cert_old)) {
  935. client_log(client, BLOG_NOTICE, "client certificate too big");
  936. goto fail2;
  937. }
  938. memcpy(client->cert_old, der.data, der.len);
  939. client->cert_old_len = der.len;
  940. // init I/O chains
  941. if (!client_init_io(client)) {
  942. goto fail2;
  943. }
  944. PORT_FreeArena(arena, PR_FALSE);
  945. CERT_DestroyCertificate(cert);
  946. // set client state
  947. client->initstatus = INITSTATUS_WAITHELLO;
  948. client_log(client, BLOG_INFO, "handshake complete");
  949. return;
  950. // handle errors
  951. fail2:
  952. PORT_FreeArena(arena, PR_FALSE);
  953. fail1:
  954. CERT_DestroyCertificate(cert);
  955. fail0:
  956. client_remove(client);
  957. }
  958. void client_handshake_read_handler (struct client_data *client, PRInt16 event)
  959. {
  960. ASSERT(client->initstatus == INITSTATUS_HANDSHAKE)
  961. ASSERT(!client->dying)
  962. ASSERT(event == PR_POLL_READ)
  963. // restart no data timer
  964. BReactor_SetTimer(&ss, &client->disconnect_timer);
  965. // continue handshake
  966. client_try_handshake(client);
  967. return;
  968. }
  969. int client_init_io (struct client_data *client)
  970. {
  971. // initialize error domain
  972. FlowErrorDomain_Init(&client->domain, (FlowErrorDomain_handler)client_error_handler, client);
  973. // init input
  974. // init source
  975. StreamRecvInterface *source_interface;
  976. if (options.ssl) {
  977. PRStreamSource_Init(&client->input_source.ssl, FlowErrorReporter_Create(&client->domain, COMPONENT_SOURCE), &client->ssl_bprfd, BReactor_PendingGroup(&ss));
  978. source_interface = PRStreamSource_GetOutput(&client->input_source.ssl);
  979. } else {
  980. StreamSocketSource_Init(&client->input_source.plain, FlowErrorReporter_Create(&client->domain, COMPONENT_SOURCE), &client->sock, BReactor_PendingGroup(&ss));
  981. source_interface = StreamSocketSource_GetOutput(&client->input_source.plain);
  982. }
  983. // init interface
  984. PacketPassInterface_Init(&client->input_interface, SC_MAX_ENC, (PacketPassInterface_handler_send)client_input_handler_send, client, BReactor_PendingGroup(&ss));
  985. // init decoder
  986. if (!PacketProtoDecoder_Init(
  987. &client->input_decoder, FlowErrorReporter_Create(&client->domain, COMPONENT_DECODER),
  988. source_interface, &client->input_interface, BReactor_PendingGroup(&ss)
  989. )) {
  990. client_log(client, BLOG_ERROR, "PacketProtoDecoder_Init failed");
  991. goto fail1;
  992. }
  993. // init output common
  994. // init sink
  995. StreamPassInterface *sink_interface;
  996. if (options.ssl) {
  997. PRStreamSink_Init(&client->output_sink.ssl, FlowErrorReporter_Create(&client->domain, COMPONENT_SINK), &client->ssl_bprfd, BReactor_PendingGroup(&ss));
  998. sink_interface = PRStreamSink_GetInput(&client->output_sink.ssl);
  999. } else {
  1000. StreamSocketSink_Init(&client->output_sink.plain, FlowErrorReporter_Create(&client->domain, COMPONENT_SINK), &client->sock, BReactor_PendingGroup(&ss));
  1001. sink_interface = StreamSocketSink_GetInput(&client->output_sink.plain);
  1002. }
  1003. // init sender
  1004. PacketStreamSender_Init(&client->output_sender, sink_interface, PACKETPROTO_ENCLEN(SC_MAX_ENC), BReactor_PendingGroup(&ss));
  1005. // init queue
  1006. PacketPassPriorityQueue_Init(&client->output_priorityqueue, PacketStreamSender_GetInput(&client->output_sender), BReactor_PendingGroup(&ss), 0);
  1007. // init output control flow
  1008. // init queue flow
  1009. PacketPassPriorityQueueFlow_Init(&client->output_control_qflow, &client->output_priorityqueue, -1);
  1010. // init PacketProtoFlow
  1011. if (!PacketProtoFlow_Init(
  1012. &client->output_control_oflow, SC_MAX_ENC, CLIENT_CONTROL_BUFFER_MIN_PACKETS,
  1013. PacketPassPriorityQueueFlow_GetInput(&client->output_control_qflow), BReactor_PendingGroup(&ss)
  1014. )) {
  1015. client_log(client, BLOG_ERROR, "PacketProtoFlow_Init failed");
  1016. goto fail2;
  1017. }
  1018. client->output_control_input = PacketProtoFlow_GetInput(&client->output_control_oflow);
  1019. client->output_control_packet_len = -1;
  1020. // init output peers flow
  1021. // init queue flow
  1022. // use lower priority than control flow (higher number)
  1023. PacketPassPriorityQueueFlow_Init(&client->output_peers_qflow, &client->output_priorityqueue, 0);
  1024. // init fair queue (for different peers)
  1025. PacketPassFairQueue_Init(&client->output_peers_fairqueue, PacketPassPriorityQueueFlow_GetInput(&client->output_peers_qflow), BReactor_PendingGroup(&ss), 0, 1);
  1026. // init list of flows
  1027. LinkedList2_Init(&client->output_peers_flows);
  1028. return 1;
  1029. fail2:
  1030. PacketPassPriorityQueueFlow_Free(&client->output_control_qflow);
  1031. // free output common
  1032. PacketPassPriorityQueue_Free(&client->output_priorityqueue);
  1033. PacketStreamSender_Free(&client->output_sender);
  1034. if (options.ssl) {
  1035. PRStreamSink_Free(&client->output_sink.ssl);
  1036. } else {
  1037. StreamSocketSink_Free(&client->output_sink.plain);
  1038. }
  1039. // free input
  1040. PacketProtoDecoder_Free(&client->input_decoder);
  1041. fail1:
  1042. PacketPassInterface_Free(&client->input_interface);
  1043. if (options.ssl) {
  1044. PRStreamSource_Free(&client->input_source.ssl);
  1045. } else {
  1046. StreamSocketSource_Free(&client->input_source.plain);
  1047. }
  1048. return 0;
  1049. }
  1050. void client_dealloc_io (struct client_data *client)
  1051. {
  1052. // allow freeing fair queue flows
  1053. PacketPassFairQueue_PrepareFree(&client->output_peers_fairqueue);
  1054. // remove flows to us
  1055. LinkedList2Node *node;
  1056. while (node = LinkedList2_GetFirst(&client->output_peers_flows)) {
  1057. struct peer_flow *flow = UPPER_OBJECT(node, struct peer_flow, dest_list_node);
  1058. ASSERT(flow->dest_client == client)
  1059. peer_flow_dealloc(flow);
  1060. }
  1061. // allow freeing priority queue flows
  1062. PacketPassPriorityQueue_PrepareFree(&client->output_priorityqueue);
  1063. // free output peers flow
  1064. PacketPassFairQueue_Free(&client->output_peers_fairqueue);
  1065. PacketPassPriorityQueueFlow_Free(&client->output_peers_qflow);
  1066. // free output control flow
  1067. PacketProtoFlow_Free(&client->output_control_oflow);
  1068. PacketPassPriorityQueueFlow_Free(&client->output_control_qflow);
  1069. // free output common
  1070. PacketPassPriorityQueue_Free(&client->output_priorityqueue);
  1071. PacketStreamSender_Free(&client->output_sender);
  1072. if (options.ssl) {
  1073. PRStreamSink_Free(&client->output_sink.ssl);
  1074. } else {
  1075. StreamSocketSink_Free(&client->output_sink.plain);
  1076. }
  1077. // free input
  1078. PacketProtoDecoder_Free(&client->input_decoder);
  1079. PacketPassInterface_Free(&client->input_interface);
  1080. if (options.ssl) {
  1081. PRStreamSource_Free(&client->input_source.ssl);
  1082. } else {
  1083. StreamSocketSource_Free(&client->input_source.plain);
  1084. }
  1085. }
  1086. void client_error_handler (struct client_data *client, int component, int code)
  1087. {
  1088. ASSERT(INITSTATUS_HASLINK(client->initstatus))
  1089. ASSERT(!client->dying)
  1090. client_log(client, BLOG_NOTICE, "error");
  1091. client_remove(client);
  1092. return;
  1093. }
  1094. int client_start_control_packet (struct client_data *client, void **data, int len)
  1095. {
  1096. ASSERT(len >= 0)
  1097. ASSERT(len <= SC_MAX_PAYLOAD)
  1098. ASSERT(!(len > 0) || data)
  1099. ASSERT(INITSTATUS_HASLINK(client->initstatus))
  1100. ASSERT(!client->dying)
  1101. ASSERT(client->output_control_packet_len == -1)
  1102. // obtain location for writing the packet
  1103. if (!BufferWriter_StartPacket(client->output_control_input, &client->output_control_packet)) {
  1104. // out of buffer, kill client
  1105. client_log(client, BLOG_NOTICE, "out of control buffer, removing");
  1106. client_remove(client);
  1107. return -1;
  1108. }
  1109. client->output_control_packet_len = len;
  1110. if (data) {
  1111. *data = client->output_control_packet + sizeof(struct sc_header);
  1112. }
  1113. return 0;
  1114. }
  1115. void client_end_control_packet (struct client_data *client, uint8_t type)
  1116. {
  1117. ASSERT(INITSTATUS_HASLINK(client->initstatus))
  1118. ASSERT(!client->dying)
  1119. ASSERT(client->output_control_packet_len >= 0)
  1120. ASSERT(client->output_control_packet_len <= SC_MAX_PAYLOAD)
  1121. // write header
  1122. struct sc_header *header = (struct sc_header *)client->output_control_packet;
  1123. header->type = htol8(type);
  1124. // finish writing packet
  1125. BufferWriter_EndPacket(client->output_control_input, sizeof(struct sc_header) + client->output_control_packet_len);
  1126. client->output_control_packet_len = -1;
  1127. }
  1128. int client_send_newclient (struct client_data *client, struct client_data *nc, int relay_server, int relay_client)
  1129. {
  1130. ASSERT(client->initstatus == INITSTATUS_COMPLETE)
  1131. ASSERT(!client->dying)
  1132. ASSERT(nc->initstatus == INITSTATUS_COMPLETE)
  1133. ASSERT(!nc->dying)
  1134. int flags = 0;
  1135. if (relay_server) {
  1136. flags |= SCID_NEWCLIENT_FLAG_RELAY_SERVER;
  1137. }
  1138. if (relay_client) {
  1139. flags |= SCID_NEWCLIENT_FLAG_RELAY_CLIENT;
  1140. }
  1141. uint8_t *cert_data = NULL;
  1142. int cert_len = 0;
  1143. if (options.ssl) {
  1144. cert_data = (client->version == SC_OLDVERSION ? nc->cert_old : nc->cert);
  1145. cert_len = (client->version == SC_OLDVERSION ? nc->cert_old_len : nc->cert_len);
  1146. }
  1147. struct sc_server_newclient *pack;
  1148. if (client_start_control_packet(client, (void **)&pack, sizeof(struct sc_server_newclient) + cert_len) < 0) {
  1149. return -1;
  1150. }
  1151. pack->id = htol16(nc->id);
  1152. pack->flags = htol16(flags);
  1153. memcpy(pack + 1, cert_data, cert_len);
  1154. client_end_control_packet(client, SCID_NEWCLIENT);
  1155. return 0;
  1156. }
  1157. int client_send_endclient (struct client_data *client, peerid_t end_id)
  1158. {
  1159. ASSERT(client->initstatus == INITSTATUS_COMPLETE)
  1160. ASSERT(!client->dying)
  1161. struct sc_server_endclient *pack;
  1162. if (client_start_control_packet(client, (void **)&pack, sizeof(struct sc_server_endclient)) < 0) {
  1163. return -1;
  1164. }
  1165. pack->id = htol16(end_id);
  1166. client_end_control_packet(client, SCID_ENDCLIENT);
  1167. return 0;
  1168. }
  1169. void client_input_handler_send (struct client_data *client, uint8_t *data, int data_len)
  1170. {
  1171. ASSERT(data_len >= 0)
  1172. ASSERT(data_len <= SC_MAX_ENC)
  1173. ASSERT(INITSTATUS_HASLINK(client->initstatus))
  1174. ASSERT(!client->dying)
  1175. if (data_len < sizeof(struct sc_header)) {
  1176. client_log(client, BLOG_NOTICE, "packet too short");
  1177. client_remove(client);
  1178. return;
  1179. }
  1180. struct sc_header *header = (struct sc_header *)data;
  1181. uint8_t type = ltoh8(header->type);
  1182. uint8_t *sc_data = data + sizeof(struct sc_header);
  1183. int sc_data_len = data_len - sizeof(struct sc_header);
  1184. ASSERT(sc_data_len >= 0)
  1185. ASSERT(sc_data_len <= SC_MAX_PAYLOAD)
  1186. // restart no data timer
  1187. BReactor_SetTimer(&ss, &client->disconnect_timer);
  1188. // accept packet
  1189. PacketPassInterface_Done(&client->input_interface);
  1190. // perform action based on packet type
  1191. switch (type) {
  1192. case SCID_KEEPALIVE:
  1193. client_log(client, BLOG_DEBUG, "received keep-alive");
  1194. return;
  1195. case SCID_CLIENTHELLO:
  1196. process_packet_hello(client, sc_data, sc_data_len);
  1197. return;
  1198. case SCID_OUTMSG:
  1199. process_packet_outmsg(client, sc_data, sc_data_len);
  1200. return;
  1201. default:
  1202. client_log(client, BLOG_NOTICE, "unknown packet type %d, removing", (int)header->type);
  1203. client_remove(client);
  1204. return;
  1205. }
  1206. }
  1207. void process_packet_hello (struct client_data *client, uint8_t *data, int data_len)
  1208. {
  1209. if (client->initstatus != INITSTATUS_WAITHELLO) {
  1210. client_log(client, BLOG_NOTICE, "hello: not expected");
  1211. client_remove(client);
  1212. return;
  1213. }
  1214. if (data_len != sizeof(struct sc_client_hello)) {
  1215. client_log(client, BLOG_NOTICE, "hello: invalid length");
  1216. client_remove(client);
  1217. return;
  1218. }
  1219. struct sc_client_hello *msg = (struct sc_client_hello *)data;
  1220. client->version = ltoh16(msg->version);
  1221. if (client->version != SC_VERSION && client->version != SC_OLDVERSION) {
  1222. client_log(client, BLOG_NOTICE, "hello: unknown version");
  1223. client_remove(client);
  1224. return;
  1225. }
  1226. client_log(client, BLOG_INFO, "received hello");
  1227. // limit socket send buffer, else our scheduling is pointless
  1228. if (BSocket_SetSendBuffer(&client->sock, CLIENT_SOCKET_SEND_BUFFER) < 0) {
  1229. BLog(BLOG_WARNING, "BSocket_SetSendBuffer failed");
  1230. }
  1231. // set client state to complete
  1232. client->initstatus = INITSTATUS_COMPLETE;
  1233. // publish client
  1234. for (LinkedList2Node *list_node = LinkedList2_GetFirst(&clients); list_node; list_node = LinkedList2Node_Next(list_node)) {
  1235. struct client_data *client2 = UPPER_OBJECT(list_node, struct client_data, list_node);
  1236. if (client2 == client || client2->initstatus != INITSTATUS_COMPLETE || client2->dying || !clients_allowed(client, client2)) {
  1237. continue;
  1238. }
  1239. // determine relay relations
  1240. int relay_to = relay_allowed(client, client2);
  1241. int relay_from = relay_allowed(client2, client);
  1242. if (!create_know(client, client2, relay_to, relay_from)) {
  1243. client_log(client, BLOG_ERROR, "failed to allocate know to %d", (int)client2->id);
  1244. goto fail;
  1245. }
  1246. if (!create_know(client2, client, relay_from, relay_to)) {
  1247. client_log(client, BLOG_ERROR, "failed to allocate know from %d", (int)client2->id);
  1248. goto fail;
  1249. }
  1250. // create flow from client to client2
  1251. if (!peer_flow_create(client, client2)) {
  1252. client_log(client, BLOG_ERROR, "failed to allocate flow to %d", (int)client2->id);
  1253. goto fail;
  1254. }
  1255. // create flow from client2 to client
  1256. if (!peer_flow_create(client2, client)) {
  1257. client_log(client, BLOG_ERROR, "failed to allocate flow from %d", (int)client2->id);
  1258. goto fail;
  1259. }
  1260. }
  1261. // send hello
  1262. struct sc_server_hello *pack;
  1263. if (client_start_control_packet(client, (void **)&pack, sizeof(struct sc_server_hello)) < 0) {
  1264. return;
  1265. }
  1266. pack->flags = htol16(0);
  1267. pack->id = htol16(client->id);
  1268. pack->clientAddr = (client->addr.type == BADDR_TYPE_IPV4 ? client->addr.ipv4.ip : htol32(0));
  1269. client_end_control_packet(client, SCID_SERVERHELLO);
  1270. return;
  1271. fail:
  1272. client_remove(client);
  1273. }
  1274. void process_packet_outmsg (struct client_data *client, uint8_t *data, int data_len)
  1275. {
  1276. if (client->initstatus != INITSTATUS_COMPLETE) {
  1277. client_log(client, BLOG_NOTICE, "outmsg: not expected");
  1278. client_remove(client);
  1279. return;
  1280. }
  1281. if (data_len < sizeof(struct sc_client_outmsg)) {
  1282. client_log(client, BLOG_NOTICE, "outmsg: wrong size");
  1283. client_remove(client);
  1284. return;
  1285. }
  1286. struct sc_client_outmsg *msg = (struct sc_client_outmsg *)data;
  1287. peerid_t id = ltoh16(msg->clientid);
  1288. int payload_size = data_len - sizeof(struct sc_client_outmsg);
  1289. if (payload_size > SC_MAX_MSGLEN) {
  1290. client_log(client, BLOG_NOTICE, "outmsg: too large payload");
  1291. client_remove(client);
  1292. return;
  1293. }
  1294. uint8_t *payload = data + sizeof(struct sc_client_outmsg);
  1295. // lookup flow to destination client
  1296. BAVLNode *node = BAVL_LookupExact(&client->peer_out_flows_tree, &id);
  1297. if (!node) {
  1298. client_log(client, BLOG_INFO, "no flow for message to %d", (int)id);
  1299. return;
  1300. }
  1301. struct peer_flow *flow = UPPER_OBJECT(node, struct peer_flow, src_tree_node);
  1302. // send packet
  1303. struct sc_server_inmsg *pack;
  1304. if (!peer_flow_start_packet(flow, (void **)&pack, sizeof(struct sc_server_inmsg) + payload_size)) {
  1305. return;
  1306. }
  1307. pack->clientid = htol16(client->id);
  1308. memcpy((uint8_t *)(pack + 1), payload, payload_size);
  1309. peer_flow_end_packet(flow, SCID_INMSG);
  1310. }
  1311. struct peer_flow * peer_flow_create (struct client_data *src_client, struct client_data *dest_client)
  1312. {
  1313. ASSERT(src_client->initstatus == INITSTATUS_COMPLETE)
  1314. ASSERT(!src_client->dying)
  1315. ASSERT(dest_client->initstatus == INITSTATUS_COMPLETE)
  1316. ASSERT(!dest_client->dying)
  1317. ASSERT(!BAVL_LookupExact(&src_client->peer_out_flows_tree, &dest_client->id))
  1318. // allocate flow structure
  1319. struct peer_flow *flow = malloc(sizeof(*flow));
  1320. if (!flow) {
  1321. goto fail0;
  1322. }
  1323. // set source and destination
  1324. flow->src_client = src_client;
  1325. flow->dest_client = dest_client;
  1326. flow->dest_client_id = dest_client->id;
  1327. // add to source list and tree
  1328. LinkedList2_Append(&flow->src_client->peer_out_flows_list, &flow->src_list_node);
  1329. ASSERT_EXECUTE(BAVL_Insert(&flow->src_client->peer_out_flows_tree, &flow->src_tree_node, NULL))
  1330. // add to destination client list
  1331. LinkedList2_Append(&flow->dest_client->output_peers_flows, &flow->dest_list_node);
  1332. // initialize I/O
  1333. PacketPassFairQueueFlow_Init(&flow->qflow, &flow->dest_client->output_peers_fairqueue);
  1334. if (!PacketProtoFlow_Init(
  1335. &flow->oflow, SC_MAX_ENC, CLIENT_PEER_FLOW_BUFFER_MIN_PACKETS,
  1336. PacketPassFairQueueFlow_GetInput(&flow->qflow), BReactor_PendingGroup(&ss)
  1337. )) {
  1338. BLog(BLOG_ERROR, "PacketProtoFlow_Init failed");
  1339. goto fail1;
  1340. }
  1341. flow->input = PacketProtoFlow_GetInput(&flow->oflow);
  1342. flow->packet_len = -1;
  1343. return flow;
  1344. fail1:
  1345. PacketPassFairQueueFlow_Free(&flow->qflow);
  1346. LinkedList2_Remove(&flow->dest_client->output_peers_flows, &flow->dest_list_node);
  1347. BAVL_Remove(&flow->src_client->peer_out_flows_tree, &flow->src_tree_node);
  1348. LinkedList2_Remove(&flow->src_client->peer_out_flows_list, &flow->src_list_node);
  1349. free(flow);
  1350. fail0:
  1351. return NULL;
  1352. }
  1353. void peer_flow_dealloc (struct peer_flow *flow)
  1354. {
  1355. PacketPassFairQueueFlow_AssertFree(&flow->qflow);
  1356. // free I/O
  1357. PacketProtoFlow_Free(&flow->oflow);
  1358. PacketPassFairQueueFlow_Free(&flow->qflow);
  1359. // remove from destination client list
  1360. LinkedList2_Remove(&flow->dest_client->output_peers_flows, &flow->dest_list_node);
  1361. // remove from source list and hash table
  1362. if (flow->src_client) {
  1363. BAVL_Remove(&flow->src_client->peer_out_flows_tree, &flow->src_tree_node);
  1364. LinkedList2_Remove(&flow->src_client->peer_out_flows_list, &flow->src_list_node);
  1365. }
  1366. // free memory
  1367. free(flow);
  1368. }
  1369. void peer_flow_disconnect (struct peer_flow *flow)
  1370. {
  1371. ASSERT(flow->src_client)
  1372. // remove from source list and hash table
  1373. BAVL_Remove(&flow->src_client->peer_out_flows_tree, &flow->src_tree_node);
  1374. LinkedList2_Remove(&flow->src_client->peer_out_flows_list, &flow->src_list_node);
  1375. // set no source
  1376. flow->src_client = NULL;
  1377. }
  1378. int peer_flow_start_packet (struct peer_flow *flow, void **data, int len)
  1379. {
  1380. ASSERT(len >= 0)
  1381. ASSERT(len <= SC_MAX_PAYLOAD)
  1382. ASSERT(!(len > 0) || data)
  1383. ASSERT(flow->dest_client->initstatus == INITSTATUS_COMPLETE)
  1384. ASSERT(!flow->dest_client->dying)
  1385. ASSERT(flow->src_client->initstatus == INITSTATUS_COMPLETE)
  1386. ASSERT(!flow->src_client->dying)
  1387. ASSERT(flow->packet_len == -1)
  1388. // obtain location for writing the packet
  1389. if (!BufferWriter_StartPacket(flow->input, &flow->packet)) {
  1390. client_log(flow->src_client, BLOG_INFO, "out of flow buffer for message to %d", (int)flow->dest_client->id);
  1391. return 0;
  1392. }
  1393. flow->packet_len = len;
  1394. if (data) {
  1395. *data = flow->packet + sizeof(struct sc_header);
  1396. }
  1397. return 1;
  1398. }
  1399. void peer_flow_end_packet (struct peer_flow *flow, uint8_t type)
  1400. {
  1401. ASSERT(flow->packet_len >= 0)
  1402. ASSERT(flow->packet_len <= SC_MAX_PAYLOAD)
  1403. // write header
  1404. struct sc_header *header = (struct sc_header *)flow->packet;
  1405. header->type = type;
  1406. // finish writing packet
  1407. BufferWriter_EndPacket(flow->input, sizeof(struct sc_header) + flow->packet_len);
  1408. flow->packet_len = -1;
  1409. }
  1410. void peer_flow_handler_canremove (struct peer_flow *flow)
  1411. {
  1412. ASSERT(!flow->src_client)
  1413. ASSERT(flow->dest_client->initstatus == INITSTATUS_COMPLETE)
  1414. ASSERT(!flow->dest_client->dying)
  1415. client_log(flow->dest_client, BLOG_DEBUG, "removing old flow");
  1416. peer_flow_dealloc(flow);
  1417. return;
  1418. }
  1419. peerid_t new_client_id (void)
  1420. {
  1421. ASSERT(clients_num < MAX_CLIENTS)
  1422. for (int i = 0; i < MAX_CLIENTS; i++) {
  1423. peerid_t id = clients_nextid++;
  1424. if (!find_client_by_id(id)) {
  1425. return id;
  1426. }
  1427. }
  1428. ASSERT(0)
  1429. return 42;
  1430. }
  1431. struct client_data * find_client_by_id (peerid_t id)
  1432. {
  1433. BAVLNode *node;
  1434. if (!(node = BAVL_LookupExact(&clients_tree, &id))) {
  1435. return NULL;
  1436. }
  1437. return UPPER_OBJECT(node, struct client_data, tree_node);
  1438. }
  1439. int clients_allowed (struct client_data *client1, struct client_data *client2)
  1440. {
  1441. ASSERT(client1->initstatus == INITSTATUS_COMPLETE)
  1442. ASSERT(!client1->dying)
  1443. ASSERT(client2->initstatus == INITSTATUS_COMPLETE)
  1444. ASSERT(!client2->dying)
  1445. if (!options.comm_predicate) {
  1446. return 1;
  1447. }
  1448. // set values to compare against
  1449. comm_predicate_p1name = (client1->common_name ? client1->common_name : "");
  1450. comm_predicate_p2name = (client2->common_name ? client2->common_name : "");
  1451. BAddr_GetIPAddr(&client1->addr, &comm_predicate_p1addr);
  1452. BAddr_GetIPAddr(&client2->addr, &comm_predicate_p2addr);
  1453. // evaluate predicate
  1454. int res = BPredicate_Eval(&comm_predicate);
  1455. if (res < 0) {
  1456. return 0;
  1457. }
  1458. return res;
  1459. }
  1460. int comm_predicate_func_p1name_cb (void *user, void **args)
  1461. {
  1462. char *arg = args[0];
  1463. return (!strcmp(arg, comm_predicate_p1name));
  1464. }
  1465. int comm_predicate_func_p2name_cb (void *user, void **args)
  1466. {
  1467. char *arg = args[0];
  1468. return (!strcmp(arg, comm_predicate_p2name));
  1469. }
  1470. int comm_predicate_func_p1addr_cb (void *user, void **args)
  1471. {
  1472. char *arg = args[0];
  1473. BIPAddr addr;
  1474. if (!BIPAddr_Resolve(&addr, arg, 1)) {
  1475. BLog(BLOG_WARNING, "failed to parse address");
  1476. return -1;
  1477. }
  1478. return BIPAddr_Compare(&addr, &comm_predicate_p1addr);
  1479. }
  1480. int comm_predicate_func_p2addr_cb (void *user, void **args)
  1481. {
  1482. char *arg = args[0];
  1483. BIPAddr addr;
  1484. if (!BIPAddr_Resolve(&addr, arg, 1)) {
  1485. BLog(BLOG_WARNING, "failed to parse address");
  1486. return -1;
  1487. }
  1488. return BIPAddr_Compare(&addr, &comm_predicate_p2addr);
  1489. }
  1490. int relay_allowed (struct client_data *client, struct client_data *relay)
  1491. {
  1492. if (!options.relay_predicate) {
  1493. return 0;
  1494. }
  1495. // set values to compare against
  1496. relay_predicate_pname = (client->common_name ? client->common_name : "");
  1497. relay_predicate_rname = (relay->common_name ? relay->common_name : "");
  1498. BAddr_GetIPAddr(&client->addr, &relay_predicate_paddr);
  1499. BAddr_GetIPAddr(&relay->addr, &relay_predicate_raddr);
  1500. // evaluate predicate
  1501. int res = BPredicate_Eval(&relay_predicate);
  1502. if (res < 0) {
  1503. return 0;
  1504. }
  1505. return res;
  1506. }
  1507. int relay_predicate_func_pname_cb (void *user, void **args)
  1508. {
  1509. char *arg = args[0];
  1510. return (!strcmp(arg, relay_predicate_pname));
  1511. }
  1512. int relay_predicate_func_rname_cb (void *user, void **args)
  1513. {
  1514. char *arg = args[0];
  1515. return (!strcmp(arg, relay_predicate_rname));
  1516. }
  1517. int relay_predicate_func_paddr_cb (void *user, void **args)
  1518. {
  1519. char *arg = args[0];
  1520. BIPAddr addr;
  1521. if (!BIPAddr_Resolve(&addr, arg, 1)) {
  1522. BLog(BLOG_ERROR, "paddr: failed to parse address");
  1523. return -1;
  1524. }
  1525. return BIPAddr_Compare(&addr, &relay_predicate_paddr);
  1526. }
  1527. int relay_predicate_func_raddr_cb (void *user, void **args)
  1528. {
  1529. char *arg = args[0];
  1530. BIPAddr addr;
  1531. if (!BIPAddr_Resolve(&addr, arg, 1)) {
  1532. BLog(BLOG_ERROR, "raddr: failed to parse address");
  1533. return -1;
  1534. }
  1535. return BIPAddr_Compare(&addr, &relay_predicate_raddr);
  1536. }
  1537. int peerid_comparator (void *unused, peerid_t *p1, peerid_t *p2)
  1538. {
  1539. if (*p1 < *p2) {
  1540. return -1;
  1541. }
  1542. if (*p1 > *p2) {
  1543. return 1;
  1544. }
  1545. return 0;
  1546. }
  1547. int create_know (struct client_data *from, struct client_data *to, int relay_server, int relay_client)
  1548. {
  1549. ASSERT(from->initstatus == INITSTATUS_COMPLETE)
  1550. ASSERT(!from->dying)
  1551. ASSERT(to->initstatus == INITSTATUS_COMPLETE)
  1552. ASSERT(!to->dying)
  1553. // allocate structure
  1554. struct peer_know *k = malloc(sizeof(*k));
  1555. if (!k) {
  1556. return 0;
  1557. }
  1558. // init arguments
  1559. k->from = from;
  1560. k->to = to;
  1561. k->relay_server = relay_server;
  1562. k->relay_client = relay_client;
  1563. // append to lists
  1564. LinkedList2_Append(&from->know_out_list, &k->from_node);
  1565. LinkedList2_Append(&to->know_in_list, &k->to_node);
  1566. // init and set inform job to inform client 'from' about client 'to'
  1567. BPending_Init(&k->inform_job, BReactor_PendingGroup(&ss), (BPending_handler)know_inform_job_handler, k);
  1568. BPending_Set(&k->inform_job);
  1569. // init uninform job
  1570. BPending_Init(&k->uninform_job, BReactor_PendingGroup(&ss), (BPending_handler)know_uninform_job_handler, k);
  1571. return 1;
  1572. }
  1573. void remove_know (struct peer_know *k)
  1574. {
  1575. // free uninform job
  1576. BPending_Free(&k->uninform_job);
  1577. // free inform job
  1578. BPending_Free(&k->inform_job);
  1579. // remove from lists
  1580. LinkedList2_Remove(&k->to->know_in_list, &k->to_node);
  1581. LinkedList2_Remove(&k->from->know_out_list, &k->from_node);
  1582. // free structure
  1583. free(k);
  1584. }
  1585. void know_inform_job_handler (struct peer_know *k)
  1586. {
  1587. ASSERT(!k->from->dying)
  1588. ASSERT(!k->to->dying)
  1589. client_send_newclient(k->from, k->to, k->relay_server, k->relay_client);
  1590. return;
  1591. }
  1592. void uninform_know (struct peer_know *k)
  1593. {
  1594. ASSERT(!k->from->dying)
  1595. ASSERT(k->to->dying)
  1596. ASSERT(!BPending_IsSet(&k->uninform_job))
  1597. // if 'from' has not been informed about 'to' yet, remove know, otherwise
  1598. // schedule informing 'from' that 'to' is no more
  1599. if (BPending_IsSet(&k->inform_job)) {
  1600. remove_know(k);
  1601. } else {
  1602. BPending_Set(&k->uninform_job);
  1603. }
  1604. }
  1605. void know_uninform_job_handler (struct peer_know *k)
  1606. {
  1607. ASSERT(!k->from->dying)
  1608. ASSERT(k->to->dying)
  1609. ASSERT(!BPending_IsSet(&k->inform_job))
  1610. struct client_data *from = k->from;
  1611. struct client_data *to = k->to;
  1612. // remove know
  1613. remove_know(k);
  1614. // uninform
  1615. client_send_endclient(from, to->id);
  1616. }