corosync-qnetd.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605
  1. /*
  2. * Copyright (c) 2015 Red Hat, Inc.
  3. *
  4. * All rights reserved.
  5. *
  6. * Author: Jan Friesse (jfriesse@redhat.com)
  7. *
  8. * This software licensed under BSD license, the text of which follows:
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions are met:
  12. *
  13. * - Redistributions of source code must retain the above copyright notice,
  14. * this list of conditions and the following disclaimer.
  15. * - Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. * - Neither the name of the Red Hat, Inc. nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  26. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  29. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  30. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  31. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  32. * THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include <config.h>
  35. #include <stdio.h>
  36. #include <nss.h>
  37. #include <pk11func.h>
  38. #include <certt.h>
  39. #include <ssl.h>
  40. #include <prio.h>
  41. #include <prnetdb.h>
  42. #include <prerror.h>
  43. #include <prinit.h>
  44. #include <getopt.h>
  45. #include <err.h>
  46. #include <keyhi.h>
  47. #include <syslog.h>
  48. #include <signal.h>
  49. #include <errno.h>
  50. #include "qnet-config.h"
  51. #include "msg.h"
  52. #include "msgio.h"
  53. #include "tlv.h"
  54. #include "nss-sock.h"
  55. #include "qnetd-client.h"
  56. #include "qnetd-client-list.h"
  57. #include "qnetd-poll-array.h"
  58. #include "qnetd-log.h"
  59. #include "dynar.h"
  60. #include "timer-list.h"
  61. #include "qnetd-algorithm.h"
  62. #include "qnetd-cluster-list.h"
  63. #include "qnetd-client-send.h"
  64. #include "utils.h"
  65. struct qnetd_instance {
  66. struct {
  67. PRFileDesc *socket;
  68. CERTCertificate *cert;
  69. SECKEYPrivateKey *private_key;
  70. } server;
  71. size_t max_client_receive_size;
  72. size_t max_client_send_buffers;
  73. size_t max_client_send_size;
  74. size_t max_clients;
  75. struct qnetd_client_list clients;
  76. struct qnetd_cluster_list clusters;
  77. struct qnetd_poll_array poll_array;
  78. enum tlv_tls_supported tls_supported;
  79. int tls_client_cert_required;
  80. const char *host_addr;
  81. uint16_t host_port;
  82. };
  83. /*
  84. * This is global variable used for comunication with main loop and signal (calls close)
  85. */
  86. PRFileDesc *global_server_socket;
  87. /*
  88. * Decision algorithms supported in this server
  89. */
  90. #define QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE 4
  91. enum tlv_decision_algorithm_type
  92. qnetd_static_supported_decision_algorithms[QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE] = {
  93. TLV_DECISION_ALGORITHM_TYPE_TEST,
  94. TLV_DECISION_ALGORITHM_TYPE_FFSPLIT,
  95. TLV_DECISION_ALGORITHM_TYPE_2NODELMS,
  96. TLV_DECISION_ALGORITHM_TYPE_LMS,
  97. };
  98. static void
  99. qnetd_err_nss(void) {
  100. qnetd_log_nss(LOG_CRIT, "NSS error");
  101. exit(1);
  102. }
  103. static void
  104. qnetd_warn_nss(void) {
  105. qnetd_log_nss(LOG_WARNING, "NSS warning");
  106. }
  107. static void
  108. qnetd_client_log_msg_decode_error(int ret)
  109. {
  110. switch (ret) {
  111. case -1:
  112. qnetd_log(LOG_WARNING, "Received message with option with invalid length");
  113. break;
  114. case -2:
  115. qnetd_log(LOG_CRIT, "Can't allocate memory");
  116. break;
  117. case -3:
  118. qnetd_log(LOG_WARNING, "Received inconsistent msg (tlv len > msg size)");
  119. break;
  120. case -4:
  121. qnetd_log(LOG_WARNING, "Received message with option with invalid value");
  122. break;
  123. default:
  124. qnetd_log(LOG_ERR, "Unknown error occured when decoding message");
  125. break;
  126. }
  127. }
  128. static int
  129. qnetd_client_msg_received_preinit(struct qnetd_instance *instance, struct qnetd_client *client,
  130. const struct msg_decoded *msg)
  131. {
  132. struct send_buffer_list_entry *send_buffer;
  133. if (msg->cluster_name == NULL) {
  134. qnetd_log(LOG_ERR, "Received preinit message without cluster name. "
  135. "Sending error reply.");
  136. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  137. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  138. return (-1);
  139. }
  140. return (0);
  141. }
  142. client->cluster_name = malloc(msg->cluster_name_len + 1);
  143. if (client->cluster_name == NULL) {
  144. qnetd_log(LOG_ERR, "Can't allocate cluster name. Sending error reply.");
  145. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  146. TLV_REPLY_ERROR_CODE_INTERNAL_ERROR) != 0) {
  147. return (-1);
  148. }
  149. return (0);
  150. }
  151. memset(client->cluster_name, 0, msg->cluster_name_len + 1);
  152. memcpy(client->cluster_name, msg->cluster_name, msg->cluster_name_len);
  153. client->cluster_name_len = msg->cluster_name_len;
  154. client->preinit_received = 1;
  155. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  156. if (send_buffer == NULL) {
  157. qnetd_log(LOG_ERR, "Can't alloc preinit reply msg from list. "
  158. "Disconnecting client connection.");
  159. return (-1);
  160. }
  161. if (msg_create_preinit_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  162. instance->tls_supported, instance->tls_client_cert_required) == 0) {
  163. qnetd_log(LOG_ERR, "Can't alloc preinit reply msg. "
  164. "Disconnecting client connection.");
  165. return (-1);
  166. };
  167. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  168. return (0);
  169. }
  170. static int
  171. qnetd_client_msg_received_unexpected_msg(struct qnetd_client *client,
  172. const struct msg_decoded *msg, const char *msg_str)
  173. {
  174. qnetd_log(LOG_ERR, "Received %s message. Sending back error message", msg_str);
  175. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  176. TLV_REPLY_ERROR_CODE_UNEXPECTED_MESSAGE) != 0) {
  177. return (-1);
  178. }
  179. return (0);
  180. }
  181. static int
  182. qnetd_client_msg_received_preinit_reply(struct qnetd_instance *instance,
  183. struct qnetd_client *client, const struct msg_decoded *msg)
  184. {
  185. return (qnetd_client_msg_received_unexpected_msg(client, msg, "preinit reply"));
  186. }
  187. static int
  188. qnetd_client_msg_received_starttls(struct qnetd_instance *instance, struct qnetd_client *client,
  189. const struct msg_decoded *msg)
  190. {
  191. PRFileDesc *new_pr_fd;
  192. if (!client->preinit_received) {
  193. qnetd_log(LOG_ERR, "Received starttls before preinit message. "
  194. "Sending error reply.");
  195. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  196. TLV_REPLY_ERROR_CODE_PREINIT_REQUIRED) != 0) {
  197. return (-1);
  198. }
  199. return (0);
  200. }
  201. if ((new_pr_fd = nss_sock_start_ssl_as_server(client->socket, instance->server.cert,
  202. instance->server.private_key, instance->tls_client_cert_required, 0, NULL)) == NULL) {
  203. qnetd_log_nss(LOG_ERR, "Can't start TLS. Disconnecting client.");
  204. return (-1);
  205. }
  206. client->tls_started = 1;
  207. client->tls_peer_certificate_verified = 0;
  208. client->socket = new_pr_fd;
  209. return (0);
  210. }
  211. static int
  212. qnetd_client_msg_received_server_error(struct qnetd_instance *instance, struct qnetd_client *client,
  213. const struct msg_decoded *msg)
  214. {
  215. return (qnetd_client_msg_received_unexpected_msg(client, msg, "server error"));
  216. }
  217. /*
  218. * 0 - Success
  219. * -1 - Disconnect client
  220. * -2 - Error reply sent, but no need to disconnect client
  221. */
  222. static int
  223. qnetd_client_check_tls(struct qnetd_instance *instance, struct qnetd_client *client,
  224. const struct msg_decoded *msg)
  225. {
  226. int check_certificate;
  227. int tls_required;
  228. CERTCertificate *peer_cert;
  229. check_certificate = 0;
  230. tls_required = 0;
  231. switch (instance->tls_supported) {
  232. case TLV_TLS_UNSUPPORTED:
  233. tls_required = 0;
  234. check_certificate = 0;
  235. break;
  236. case TLV_TLS_SUPPORTED:
  237. tls_required = 0;
  238. if (client->tls_started && instance->tls_client_cert_required &&
  239. !client->tls_peer_certificate_verified) {
  240. check_certificate = 1;
  241. }
  242. break;
  243. case TLV_TLS_REQUIRED:
  244. tls_required = 1;
  245. if (instance->tls_client_cert_required && !client->tls_peer_certificate_verified) {
  246. check_certificate = 1;
  247. }
  248. break;
  249. default:
  250. errx(1, "Unhandled instance tls supported %u\n", instance->tls_supported);
  251. break;
  252. }
  253. if (tls_required && !client->tls_started) {
  254. qnetd_log(LOG_ERR, "TLS is required but doesn't started yet. "
  255. "Sending back error message");
  256. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  257. TLV_REPLY_ERROR_CODE_TLS_REQUIRED) != 0) {
  258. return (-1);
  259. }
  260. return (-2);
  261. }
  262. if (check_certificate) {
  263. peer_cert = SSL_PeerCertificate(client->socket);
  264. if (peer_cert == NULL) {
  265. qnetd_log(LOG_ERR, "Client doesn't sent valid certificate. "
  266. "Disconnecting client");
  267. return (-1);
  268. }
  269. if (CERT_VerifyCertName(peer_cert, client->cluster_name) != SECSuccess) {
  270. qnetd_log(LOG_ERR, "Client doesn't sent certificate with valid CN. "
  271. "Disconnecting client");
  272. CERT_DestroyCertificate(peer_cert);
  273. return (-1);
  274. }
  275. CERT_DestroyCertificate(peer_cert);
  276. client->tls_peer_certificate_verified = 1;
  277. }
  278. return (0);
  279. }
  280. static int
  281. qnetd_client_msg_received_init(struct qnetd_instance *instance, struct qnetd_client *client,
  282. const struct msg_decoded *msg)
  283. {
  284. int res;
  285. size_t zi;
  286. enum msg_type *supported_msgs;
  287. size_t no_supported_msgs;
  288. enum tlv_opt_type *supported_opts;
  289. size_t no_supported_opts;
  290. struct send_buffer_list_entry *send_buffer;
  291. enum tlv_reply_error_code reply_error_code;
  292. struct qnetd_cluster *cluster;
  293. supported_msgs = NULL;
  294. supported_opts = NULL;
  295. no_supported_msgs = 0;
  296. no_supported_opts = 0;
  297. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  298. if ((res = qnetd_client_check_tls(instance, client, msg)) != 0) {
  299. return (res == -1 ? -1 : 0);
  300. }
  301. if (!client->preinit_received) {
  302. qnetd_log(LOG_ERR, "Received init before preinit message. Sending error reply.");
  303. reply_error_code = TLV_REPLY_ERROR_CODE_PREINIT_REQUIRED;
  304. }
  305. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->node_id_set) {
  306. qnetd_log(LOG_ERR, "Received init message without node id set. "
  307. "Sending error reply.");
  308. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  309. } else {
  310. client->node_id_set = 1;
  311. client->node_id = msg->node_id;
  312. }
  313. if (msg->supported_messages != NULL) {
  314. /*
  315. * Client sent supported messages. For now this is ignored but in the future
  316. * this may be used to ensure backward compatibility.
  317. */
  318. /*
  319. for (i = 0; i < msg->no_supported_messages; i++) {
  320. qnetd_log(LOG_DEBUG, "Client supports %u message",
  321. (int)msg->supported_messages[i]);
  322. }
  323. */
  324. /*
  325. * Sent back supported messages
  326. */
  327. msg_get_supported_messages(&supported_msgs, &no_supported_msgs);
  328. }
  329. if (msg->supported_options != NULL) {
  330. /*
  331. * Client sent supported options. For now this is ignored but in the future
  332. * this may be used to ensure backward compatibility.
  333. */
  334. /*
  335. for (i = 0; i < msg->no_supported_options; i++) {
  336. qnetd_log(LOG_DEBUG, "Client supports %u option",
  337. (int)msg->supported_messages[i]);
  338. }
  339. */
  340. /*
  341. * Send back supported options
  342. */
  343. tlv_get_supported_options(&supported_opts, &no_supported_opts);
  344. }
  345. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->decision_algorithm_set) {
  346. qnetd_log(LOG_ERR, "Received init message without decision algorithm. "
  347. "Sending error reply.");
  348. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  349. } else {
  350. /*
  351. * Check if decision algorithm requested by client is supported
  352. */
  353. res = 0;
  354. for (zi = 0; zi < QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE && !res; zi++) {
  355. if (qnetd_static_supported_decision_algorithms[zi] ==
  356. msg->decision_algorithm) {
  357. res = 1;
  358. }
  359. }
  360. if (!res) {
  361. qnetd_log(LOG_ERR, "Client requested unsupported decision algorithm %u. "
  362. "Sending error reply.", msg->decision_algorithm);
  363. reply_error_code = TLV_REPLY_ERROR_CODE_UNSUPPORTED_DECISION_ALGORITHM;
  364. }
  365. client->decision_algorithm = msg->decision_algorithm;
  366. }
  367. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  368. cluster = qnetd_cluster_list_add_client(&instance->clusters, client);
  369. if (cluster == NULL) {
  370. qnetd_log(LOG_ERR, "Can't add client to cluster list. "
  371. "Sending error reply.");
  372. reply_error_code = TLV_REPLY_ERROR_CODE_INTERNAL_ERROR;
  373. } else {
  374. client->cluster = cluster;
  375. }
  376. }
  377. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  378. reply_error_code = qnetd_algorithm_client_init(client);
  379. }
  380. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  381. /*
  382. * Correct init received
  383. */
  384. client->init_received = 1;
  385. }
  386. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  387. if (send_buffer == NULL) {
  388. qnetd_log(LOG_ERR, "Can't alloc init reply msg from list. "
  389. "Disconnecting client connection.");
  390. return (-1);
  391. }
  392. if (msg_create_init_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  393. reply_error_code,
  394. supported_msgs, no_supported_msgs, supported_opts, no_supported_opts,
  395. instance->max_client_receive_size, instance->max_client_send_size,
  396. qnetd_static_supported_decision_algorithms,
  397. QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE) == -1) {
  398. qnetd_log(LOG_ERR, "Can't alloc init reply msg. Disconnecting client connection.");
  399. return (-1);
  400. }
  401. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  402. return (0);
  403. }
  404. static int
  405. qnetd_client_msg_received_init_reply(struct qnetd_instance *instance, struct qnetd_client *client,
  406. const struct msg_decoded *msg)
  407. {
  408. return (qnetd_client_msg_received_unexpected_msg(client, msg, "init reply"));
  409. }
  410. static int
  411. qnetd_client_msg_received_set_option_reply(struct qnetd_instance *instance,
  412. struct qnetd_client *client, const struct msg_decoded *msg)
  413. {
  414. return (qnetd_client_msg_received_unexpected_msg(client, msg, "set option reply"));
  415. }
  416. static int
  417. qnetd_client_msg_received_set_option(struct qnetd_instance *instance, struct qnetd_client *client,
  418. const struct msg_decoded *msg)
  419. {
  420. int res;
  421. struct send_buffer_list_entry *send_buffer;
  422. if ((res = qnetd_client_check_tls(instance, client, msg)) != 0) {
  423. return (res == -1 ? -1 : 0);
  424. }
  425. if (!client->init_received) {
  426. qnetd_log(LOG_ERR, "Received set option message before init message. "
  427. "Sending error reply.");
  428. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  429. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  430. return (-1);
  431. }
  432. return (0);
  433. }
  434. if (msg->heartbeat_interval_set) {
  435. /*
  436. * Check if heartbeat interval is valid
  437. */
  438. if (msg->heartbeat_interval != 0 &&
  439. (msg->heartbeat_interval < QNETD_HEARTBEAT_INTERVAL_MIN ||
  440. msg->heartbeat_interval > QNETD_HEARTBEAT_INTERVAL_MAX)) {
  441. qnetd_log(LOG_ERR, "Client requested invalid heartbeat interval %u. "
  442. "Sending error reply.", msg->heartbeat_interval);
  443. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  444. TLV_REPLY_ERROR_CODE_INVALID_HEARTBEAT_INTERVAL) != 0) {
  445. return (-1);
  446. }
  447. return (0);
  448. }
  449. client->heartbeat_interval = msg->heartbeat_interval;
  450. }
  451. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  452. if (send_buffer == NULL) {
  453. qnetd_log(LOG_ERR, "Can't alloc set option reply msg from list. "
  454. "Disconnecting client connection.");
  455. return (-1);
  456. }
  457. if (msg_create_set_option_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  458. client->decision_algorithm, client->heartbeat_interval) == -1) {
  459. qnetd_log(LOG_ERR, "Can't alloc set option reply msg. "
  460. "Disconnecting client connection.");
  461. return (-1);
  462. }
  463. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  464. return (0);
  465. }
  466. static int
  467. qnetd_client_msg_received_echo_reply(struct qnetd_instance *instance, struct qnetd_client *client,
  468. const struct msg_decoded *msg)
  469. {
  470. return (qnetd_client_msg_received_unexpected_msg(client, msg, "echo reply"));
  471. }
  472. static int
  473. qnetd_client_msg_received_echo_request(struct qnetd_instance *instance, struct qnetd_client *client,
  474. const struct msg_decoded *msg, const struct dynar *msg_orig)
  475. {
  476. int res;
  477. struct send_buffer_list_entry *send_buffer;
  478. if ((res = qnetd_client_check_tls(instance, client, msg)) != 0) {
  479. return (res == -1 ? -1 : 0);
  480. }
  481. if (!client->init_received) {
  482. qnetd_log(LOG_ERR, "Received echo request before init message. "
  483. "Sending error reply.");
  484. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  485. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  486. return (-1);
  487. }
  488. return (0);
  489. }
  490. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  491. if (send_buffer == NULL) {
  492. qnetd_log(LOG_ERR, "Can't alloc echo reply msg from list. "
  493. "Disconnecting client connection.");
  494. return (-1);
  495. }
  496. if (msg_create_echo_reply(&send_buffer->buffer, msg_orig) == -1) {
  497. qnetd_log(LOG_ERR, "Can't alloc echo reply msg. Disconnecting client connection.");
  498. return (-1);
  499. }
  500. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  501. return (0);
  502. }
  503. static int
  504. qnetd_client_msg_received_node_list(struct qnetd_instance *instance, struct qnetd_client *client,
  505. const struct msg_decoded *msg)
  506. {
  507. int res;
  508. struct send_buffer_list_entry *send_buffer;
  509. enum tlv_reply_error_code reply_error_code;
  510. enum tlv_vote result_vote;
  511. int add_result_vote;
  512. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  513. if ((res = qnetd_client_check_tls(instance, client, msg)) != 0) {
  514. return (res == -1 ? -1 : 0);
  515. }
  516. if (!client->init_received) {
  517. qnetd_log(LOG_ERR, "Received node list message before init message. "
  518. "Sending error reply.");
  519. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  520. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  521. return (-1);
  522. }
  523. return (0);
  524. }
  525. if (!msg->node_list_type_set) {
  526. qnetd_log(LOG_ERR, "Received node list message without node list type set. "
  527. "Sending error reply.");
  528. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  529. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  530. return (-1);
  531. }
  532. return (0);
  533. }
  534. if (!msg->seq_number_set) {
  535. qnetd_log(LOG_ERR, "Received node list message without seq number set. "
  536. "Sending error reply.");
  537. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  538. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  539. return (-1);
  540. }
  541. return (0);
  542. }
  543. add_result_vote = 1;
  544. switch (msg->node_list_type) {
  545. case TLV_NODE_LIST_TYPE_INITIAL_CONFIG:
  546. case TLV_NODE_LIST_TYPE_CHANGED_CONFIG:
  547. reply_error_code = qnetd_algorithm_config_node_list_received(client,
  548. msg->seq_number, msg->config_version_set, msg->config_version,
  549. &msg->nodes,
  550. (msg->node_list_type == TLV_NODE_LIST_TYPE_INITIAL_CONFIG),
  551. &result_vote);
  552. break;
  553. case TLV_NODE_LIST_TYPE_MEMBERSHIP:
  554. if (!msg->ring_id_set) {
  555. qnetd_log(LOG_ERR, "Received node list message without ring id number set. "
  556. "Sending error reply.");
  557. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  558. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  559. return (-1);
  560. }
  561. return (0);
  562. }
  563. reply_error_code = qnetd_algorithm_membership_node_list_received(client,
  564. msg->seq_number, &msg->ring_id, &msg->nodes, &result_vote);
  565. break;
  566. case TLV_NODE_LIST_TYPE_QUORUM:
  567. if (!msg->quorate_set) {
  568. qnetd_log(LOG_ERR, "Received quorum list message without quorate set. "
  569. "Sending error reply.");
  570. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  571. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  572. return (-1);
  573. }
  574. return (0);
  575. }
  576. reply_error_code = qnetd_algorithm_quorum_node_list_received(client,
  577. msg->seq_number,msg->quorate, &msg->nodes);
  578. add_result_vote = 0;
  579. break;
  580. default:
  581. errx(1, "qnetd_client_msg_received_node_list fatal error. "
  582. "Unhandled node_list_type");
  583. break;
  584. }
  585. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  586. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  587. "Sending error reply.");
  588. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  589. reply_error_code) != 0) {
  590. return (-1);
  591. }
  592. return (0);
  593. }
  594. /*
  595. * Store node list for future use
  596. */
  597. switch (msg->node_list_type) {
  598. case TLV_NODE_LIST_TYPE_INITIAL_CONFIG:
  599. case TLV_NODE_LIST_TYPE_CHANGED_CONFIG:
  600. node_list_free(&client->configuration_node_list);
  601. if (node_list_clone(&client->configuration_node_list, &msg->nodes) == -1) {
  602. qnetd_log(LOG_ERR, "Can't alloc config node list clone. "
  603. "Disconnecting client connection.");
  604. return (-1);
  605. }
  606. break;
  607. case TLV_NODE_LIST_TYPE_MEMBERSHIP:
  608. node_list_free(&client->last_membership_node_list);
  609. if (node_list_clone(&client->last_membership_node_list, &msg->nodes) == -1) {
  610. qnetd_log(LOG_ERR, "Can't alloc membership node list clone. "
  611. "Disconnecting client connection.");
  612. return (-1);
  613. }
  614. break;
  615. case TLV_NODE_LIST_TYPE_QUORUM:
  616. node_list_free(&client->last_quorum_node_list);
  617. if (node_list_clone(&client->last_quorum_node_list, &msg->nodes) == -1) {
  618. qnetd_log(LOG_ERR, "Can't alloc quorum node list clone. "
  619. "Disconnecting client connection.");
  620. return (-1);
  621. }
  622. break;
  623. default:
  624. errx(1, "qnetd_client_msg_received_node_list fatal error. "
  625. "Unhandled node_list_type");
  626. break;
  627. }
  628. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  629. if (send_buffer == NULL) {
  630. qnetd_log(LOG_ERR, "Can't alloc node list reply msg from list. "
  631. "Disconnecting client connection.");
  632. return (-1);
  633. }
  634. if (msg_create_node_list_reply(&send_buffer->buffer, msg->seq_number, add_result_vote,
  635. result_vote) == -1) {
  636. qnetd_log(LOG_ERR, "Can't alloc node list reply msg. "
  637. "Disconnecting client connection.");
  638. return (-1);
  639. }
  640. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  641. return (0);
  642. }
  643. static int
  644. qnetd_client_msg_received_node_list_reply(struct qnetd_instance *instance,
  645. struct qnetd_client *client, const struct msg_decoded *msg)
  646. {
  647. return (qnetd_client_msg_received_unexpected_msg(client, msg, "node list reply"));
  648. }
  649. static int
  650. qnetd_client_msg_received_ask_for_vote(struct qnetd_instance *instance, struct qnetd_client *client,
  651. const struct msg_decoded *msg)
  652. {
  653. int res;
  654. struct send_buffer_list_entry *send_buffer;
  655. enum tlv_reply_error_code reply_error_code;
  656. enum tlv_vote result_vote;
  657. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  658. if ((res = qnetd_client_check_tls(instance, client, msg)) != 0) {
  659. return (res == -1 ? -1 : 0);
  660. }
  661. if (!client->init_received) {
  662. qnetd_log(LOG_ERR, "Received ask for vote message before init message. "
  663. "Sending error reply.");
  664. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  665. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  666. return (-1);
  667. }
  668. return (0);
  669. }
  670. if (!msg->seq_number_set) {
  671. qnetd_log(LOG_ERR, "Received ask for vote message without seq number set. "
  672. "Sending error reply.");
  673. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  674. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  675. return (-1);
  676. }
  677. return (0);
  678. }
  679. reply_error_code = qnetd_algorithm_ask_for_vote_received(client, msg->seq_number,
  680. &result_vote);
  681. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  682. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  683. "Sending error reply.");
  684. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  685. reply_error_code) != 0) {
  686. return (-1);
  687. }
  688. return (0);
  689. }
  690. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  691. if (send_buffer == NULL) {
  692. qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg from list. "
  693. "Disconnecting client connection.");
  694. return (-1);
  695. }
  696. if (msg_create_ask_for_vote_reply(&send_buffer->buffer, msg->seq_number,
  697. result_vote) == -1) {
  698. qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg. "
  699. "Disconnecting client connection.");
  700. return (-1);
  701. }
  702. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  703. return (0);
  704. }
  705. static int
  706. qnetd_client_msg_received_ask_for_vote_reply(struct qnetd_instance *instance,
  707. struct qnetd_client *client, const struct msg_decoded *msg)
  708. {
  709. return (qnetd_client_msg_received_unexpected_msg(client, msg, "ask for vote reply"));
  710. }
  711. static int
  712. qnetd_client_msg_received_vote_info(struct qnetd_instance *instance, struct qnetd_client *client,
  713. const struct msg_decoded *msg)
  714. {
  715. return (qnetd_client_msg_received_unexpected_msg(client, msg, "vote info"));
  716. }
  717. static int
  718. qnetd_client_msg_received_vote_info_reply(struct qnetd_instance *instance,
  719. struct qnetd_client *client, const struct msg_decoded *msg)
  720. {
  721. int res;
  722. enum tlv_reply_error_code reply_error_code;
  723. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  724. if ((res = qnetd_client_check_tls(instance, client, msg)) != 0) {
  725. return (res == -1 ? -1 : 0);
  726. }
  727. if (!client->init_received) {
  728. qnetd_log(LOG_ERR, "Received vote info reply before init message. "
  729. "Sending error reply.");
  730. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  731. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  732. return (-1);
  733. }
  734. return (0);
  735. }
  736. if (!msg->seq_number_set) {
  737. qnetd_log(LOG_ERR, "Received vote info reply message without seq number set. "
  738. "Sending error reply.");
  739. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  740. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  741. return (-1);
  742. }
  743. return (0);
  744. }
  745. reply_error_code = qnetd_algorithm_vote_info_reply_received(client, msg->seq_number);
  746. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  747. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  748. "Sending error reply.");
  749. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  750. reply_error_code) != 0) {
  751. return (-1);
  752. }
  753. return (0);
  754. }
  755. return (0);
  756. }
  757. static int
  758. qnetd_client_msg_received(struct qnetd_instance *instance, struct qnetd_client *client)
  759. {
  760. struct msg_decoded msg;
  761. int res;
  762. int ret_val;
  763. msg_decoded_init(&msg);
  764. res = msg_decode(&client->receive_buffer, &msg);
  765. if (res != 0) {
  766. /*
  767. * Error occurred. Send server error.
  768. */
  769. qnetd_client_log_msg_decode_error(res);
  770. qnetd_log(LOG_INFO, "Sending back error message");
  771. if (qnetd_client_send_err(client, msg.seq_number_set, msg.seq_number,
  772. TLV_REPLY_ERROR_CODE_ERROR_DECODING_MSG) != 0) {
  773. return (-1);
  774. }
  775. return (0);
  776. }
  777. ret_val = 0;
  778. switch (msg.type) {
  779. case MSG_TYPE_PREINIT:
  780. ret_val = qnetd_client_msg_received_preinit(instance, client, &msg);
  781. break;
  782. case MSG_TYPE_PREINIT_REPLY:
  783. ret_val = qnetd_client_msg_received_preinit_reply(instance, client, &msg);
  784. break;
  785. case MSG_TYPE_STARTTLS:
  786. ret_val = qnetd_client_msg_received_starttls(instance, client, &msg);
  787. break;
  788. case MSG_TYPE_INIT:
  789. ret_val = qnetd_client_msg_received_init(instance, client, &msg);
  790. break;
  791. case MSG_TYPE_INIT_REPLY:
  792. ret_val = qnetd_client_msg_received_init_reply(instance, client, &msg);
  793. break;
  794. case MSG_TYPE_SERVER_ERROR:
  795. ret_val = qnetd_client_msg_received_server_error(instance, client, &msg);
  796. break;
  797. case MSG_TYPE_SET_OPTION:
  798. ret_val = qnetd_client_msg_received_set_option(instance, client, &msg);
  799. break;
  800. case MSG_TYPE_SET_OPTION_REPLY:
  801. ret_val = qnetd_client_msg_received_set_option_reply(instance, client, &msg);
  802. break;
  803. case MSG_TYPE_ECHO_REQUEST:
  804. ret_val = qnetd_client_msg_received_echo_request(instance, client, &msg,
  805. &client->receive_buffer);
  806. break;
  807. case MSG_TYPE_ECHO_REPLY:
  808. ret_val = qnetd_client_msg_received_echo_reply(instance, client, &msg);
  809. break;
  810. case MSG_TYPE_NODE_LIST:
  811. ret_val = qnetd_client_msg_received_node_list(instance, client, &msg);
  812. break;
  813. case MSG_TYPE_NODE_LIST_REPLY:
  814. ret_val = qnetd_client_msg_received_node_list_reply(instance, client, &msg);
  815. break;
  816. case MSG_TYPE_ASK_FOR_VOTE:
  817. ret_val = qnetd_client_msg_received_ask_for_vote(instance, client, &msg);
  818. break;
  819. case MSG_TYPE_ASK_FOR_VOTE_REPLY:
  820. ret_val = qnetd_client_msg_received_ask_for_vote_reply(instance, client, &msg);
  821. break;
  822. case MSG_TYPE_VOTE_INFO:
  823. ret_val = qnetd_client_msg_received_vote_info(instance, client, &msg);
  824. break;
  825. case MSG_TYPE_VOTE_INFO_REPLY:
  826. ret_val = qnetd_client_msg_received_vote_info_reply(instance, client, &msg);
  827. break;
  828. default:
  829. qnetd_log(LOG_ERR, "Unsupported message %u received from client. "
  830. "Sending back error message", msg.type);
  831. if (qnetd_client_send_err(client, msg.seq_number_set, msg.seq_number,
  832. TLV_REPLY_ERROR_CODE_UNSUPPORTED_MESSAGE) != 0) {
  833. ret_val = -1;
  834. }
  835. break;
  836. }
  837. msg_decoded_destroy(&msg);
  838. return (ret_val);
  839. }
  840. static int
  841. qnetd_client_net_write_finished(struct qnetd_instance *instance, struct qnetd_client *client)
  842. {
  843. /*
  844. * Callback is currently unused
  845. */
  846. return (0);
  847. }
  848. static int
  849. qnetd_client_net_write(struct qnetd_instance *instance, struct qnetd_client *client)
  850. {
  851. int res;
  852. struct send_buffer_list_entry *send_buffer;
  853. send_buffer = send_buffer_list_get_active(&client->send_buffer_list);
  854. if (send_buffer == NULL) {
  855. qnetd_log_nss(LOG_CRIT, "send_buffer_list_get_active returned NULL");
  856. return (-1);
  857. }
  858. res = msgio_write(client->socket, &send_buffer->buffer,
  859. &send_buffer->msg_already_sent_bytes);
  860. if (res == 1) {
  861. send_buffer_list_delete(&client->send_buffer_list, send_buffer);
  862. if (qnetd_client_net_write_finished(instance, client) == -1) {
  863. return (-1);
  864. }
  865. }
  866. if (res == -1) {
  867. qnetd_log_nss(LOG_CRIT, "PR_Send returned 0");
  868. return (-1);
  869. }
  870. if (res == -2) {
  871. qnetd_log_nss(LOG_ERR, "Unhandled error when sending message to client");
  872. return (-1);
  873. }
  874. return (0);
  875. }
  876. /*
  877. * -1 means end of connection (EOF) or some other unhandled error. 0 = success
  878. */
  879. static int
  880. qnetd_client_net_read(struct qnetd_instance *instance, struct qnetd_client *client)
  881. {
  882. int res;
  883. int ret_val;
  884. int orig_skipping_msg;
  885. orig_skipping_msg = client->skipping_msg;
  886. res = msgio_read(client->socket, &client->receive_buffer,
  887. &client->msg_already_received_bytes, &client->skipping_msg);
  888. if (!orig_skipping_msg && client->skipping_msg) {
  889. qnetd_log(LOG_DEBUG, "msgio_read set skipping_msg");
  890. }
  891. ret_val = 0;
  892. switch (res) {
  893. case 0:
  894. /*
  895. * Partial read
  896. */
  897. break;
  898. case -1:
  899. qnetd_log(LOG_DEBUG, "Client closed connection");
  900. ret_val = -1;
  901. break;
  902. case -2:
  903. qnetd_log_nss(LOG_ERR, "Unhandled error when reading from client. "
  904. "Disconnecting client");
  905. ret_val = -1;
  906. break;
  907. case -3:
  908. qnetd_log(LOG_ERR, "Can't store message header from client. Disconnecting client");
  909. ret_val = -1;
  910. break;
  911. case -4:
  912. qnetd_log(LOG_ERR, "Can't store message from client. Skipping message");
  913. client->skipping_msg_reason = TLV_REPLY_ERROR_CODE_ERROR_DECODING_MSG;
  914. break;
  915. case -5:
  916. qnetd_log(LOG_WARNING, "Client sent unsupported msg type %u. Skipping message",
  917. msg_get_type(&client->receive_buffer));
  918. client->skipping_msg_reason = TLV_REPLY_ERROR_CODE_UNSUPPORTED_MESSAGE;
  919. break;
  920. case -6:
  921. qnetd_log(LOG_WARNING,
  922. "Client wants to send too long message %u bytes. Skipping message",
  923. msg_get_len(&client->receive_buffer));
  924. client->skipping_msg_reason = TLV_REPLY_ERROR_CODE_MESSAGE_TOO_LONG;
  925. break;
  926. case 1:
  927. /*
  928. * Full message received / skipped
  929. */
  930. if (!client->skipping_msg) {
  931. if (qnetd_client_msg_received(instance, client) == -1) {
  932. ret_val = -1;
  933. }
  934. } else {
  935. if (qnetd_client_send_err(client, 0, 0, client->skipping_msg_reason) != 0) {
  936. ret_val = -1;
  937. }
  938. }
  939. client->skipping_msg = 0;
  940. client->skipping_msg_reason = TLV_REPLY_ERROR_CODE_NO_ERROR;
  941. client->msg_already_received_bytes = 0;
  942. dynar_clean(&client->receive_buffer);
  943. break;
  944. default:
  945. errx(1, "Unhandled msgio_read error %d\n", res);
  946. break;
  947. }
  948. return (ret_val);
  949. }
  950. static int
  951. qnetd_client_accept(struct qnetd_instance *instance)
  952. {
  953. PRNetAddr client_addr;
  954. PRFileDesc *client_socket;
  955. struct qnetd_client *client;
  956. if ((client_socket = PR_Accept(instance->server.socket, &client_addr,
  957. PR_INTERVAL_NO_TIMEOUT)) == NULL) {
  958. qnetd_log_nss(LOG_ERR, "Can't accept connection");
  959. return (-1);
  960. }
  961. if (nss_sock_set_nonblocking(client_socket) != 0) {
  962. qnetd_log_nss(LOG_ERR, "Can't set client socket to non blocking mode");
  963. PR_Close(client_socket);
  964. return (-1);
  965. }
  966. if (instance->max_clients != 0 &&
  967. qnetd_client_list_no_clients(&instance->clients) >= instance->max_clients) {
  968. qnetd_log(LOG_ERR, "Maximum clients reached. Not accepting connection");
  969. PR_Close(client_socket);
  970. return (-1);
  971. }
  972. client = qnetd_client_list_add(&instance->clients, client_socket, &client_addr,
  973. instance->max_client_receive_size, instance->max_client_send_buffers,
  974. instance->max_client_send_size);
  975. if (client == NULL) {
  976. qnetd_log(LOG_ERR, "Can't add client to list");
  977. PR_Close(client_socket);
  978. return (-2);
  979. }
  980. return (0);
  981. }
  982. static void
  983. qnetd_client_disconnect(struct qnetd_instance *instance, struct qnetd_client *client,
  984. int server_going_down)
  985. {
  986. qnetd_algorithm_client_disconnect(client, server_going_down);
  987. PR_Close(client->socket);
  988. if (client->cluster != NULL) {
  989. qnetd_cluster_list_del_client(&instance->clusters, client->cluster, client);
  990. }
  991. qnetd_client_list_del(&instance->clients, client);
  992. }
  993. static int
  994. qnetd_poll(struct qnetd_instance *instance)
  995. {
  996. struct qnetd_client *client;
  997. struct qnetd_client *client_next;
  998. PRPollDesc *pfds;
  999. PRInt32 poll_res;
  1000. int i;
  1001. int client_disconnect;
  1002. client = NULL;
  1003. client_disconnect = 0;
  1004. pfds = qnetd_poll_array_create_from_client_list(&instance->poll_array,
  1005. &instance->clients, instance->server.socket, PR_POLL_READ);
  1006. if (pfds == NULL) {
  1007. return (-1);
  1008. }
  1009. if ((poll_res = PR_Poll(pfds, qnetd_poll_array_size(&instance->poll_array),
  1010. PR_INTERVAL_NO_TIMEOUT)) > 0) {
  1011. /*
  1012. * Walk thru pfds array and process events
  1013. */
  1014. for (i = 0; i < qnetd_poll_array_size(&instance->poll_array); i++) {
  1015. /*
  1016. * Also traverse clients list
  1017. */
  1018. if (i > 0) {
  1019. if (i == 1) {
  1020. client = TAILQ_FIRST(&instance->clients);
  1021. client_next = TAILQ_NEXT(client, entries);
  1022. } else {
  1023. client = client_next;
  1024. client_next = TAILQ_NEXT(client, entries);
  1025. }
  1026. }
  1027. client_disconnect = 0;
  1028. if (!client_disconnect && pfds[i].out_flags & PR_POLL_READ) {
  1029. if (i == 0) {
  1030. qnetd_client_accept(instance);
  1031. } else {
  1032. if (qnetd_client_net_read(instance, client) == -1) {
  1033. client_disconnect = 1;
  1034. }
  1035. }
  1036. }
  1037. if (!client_disconnect && pfds[i].out_flags & PR_POLL_WRITE) {
  1038. if (i == 0) {
  1039. /*
  1040. * Poll write on listen socket -> fatal error
  1041. */
  1042. qnetd_log(LOG_CRIT, "POLL_WRITE on listening socket");
  1043. return (-1);
  1044. } else {
  1045. if (qnetd_client_net_write(instance, client) == -1) {
  1046. client_disconnect = 1;
  1047. }
  1048. }
  1049. }
  1050. if (!client_disconnect &&
  1051. pfds[i].out_flags &
  1052. (PR_POLL_ERR|PR_POLL_NVAL|PR_POLL_HUP|PR_POLL_EXCEPT)) {
  1053. if (i == 0) {
  1054. if (pfds[i].out_flags != PR_POLL_NVAL) {
  1055. /*
  1056. * Poll ERR on listening socket is fatal error.
  1057. * POLL_NVAL is used as a signal to quit poll loop.
  1058. */
  1059. qnetd_log(LOG_CRIT, "POLL_ERR (%u) on listening "
  1060. "socket", pfds[i].out_flags);
  1061. } else {
  1062. qnetd_log(LOG_DEBUG, "Listening socket is closed");
  1063. }
  1064. return (-1);
  1065. } else {
  1066. qnetd_log(LOG_DEBUG, "POLL_ERR (%u) on client socket. "
  1067. "Disconnecting.", pfds[i].out_flags);
  1068. client_disconnect = 1;
  1069. }
  1070. }
  1071. /*
  1072. * If client is scheduled for disconnect, disconnect it
  1073. */
  1074. if (client_disconnect) {
  1075. qnetd_client_disconnect(instance, client, 0);
  1076. }
  1077. }
  1078. }
  1079. return (0);
  1080. }
  1081. static int
  1082. qnetd_instance_init_certs(struct qnetd_instance *instance)
  1083. {
  1084. instance->server.cert = PK11_FindCertFromNickname(QNETD_CERT_NICKNAME, NULL);
  1085. if (instance->server.cert == NULL) {
  1086. return (-1);
  1087. }
  1088. instance->server.private_key = PK11_FindKeyByAnyCert(instance->server.cert, NULL);
  1089. if (instance->server.private_key == NULL) {
  1090. return (-1);
  1091. }
  1092. return (0);
  1093. }
  1094. static int
  1095. qnetd_instance_init(struct qnetd_instance *instance, size_t max_client_receive_size,
  1096. size_t max_client_send_buffers, size_t max_client_send_size,
  1097. enum tlv_tls_supported tls_supported, int tls_client_cert_required, size_t max_clients)
  1098. {
  1099. memset(instance, 0, sizeof(*instance));
  1100. qnetd_poll_array_init(&instance->poll_array);
  1101. qnetd_client_list_init(&instance->clients);
  1102. qnetd_cluster_list_init(&instance->clusters);
  1103. instance->max_client_receive_size = max_client_receive_size;
  1104. instance->max_client_send_buffers = max_client_send_buffers;
  1105. instance->max_client_send_size = max_client_send_size;
  1106. instance->tls_supported = tls_supported;
  1107. instance->tls_client_cert_required = tls_client_cert_required;
  1108. instance->max_clients = max_clients;
  1109. return (0);
  1110. }
  1111. static int
  1112. qnetd_instance_destroy(struct qnetd_instance *instance)
  1113. {
  1114. struct qnetd_client *client;
  1115. struct qnetd_client *client_next;
  1116. client = TAILQ_FIRST(&instance->clients);
  1117. while (client != NULL) {
  1118. client_next = TAILQ_NEXT(client, entries);
  1119. qnetd_client_disconnect(instance, client, 1);
  1120. client = client_next;
  1121. }
  1122. qnetd_poll_array_destroy(&instance->poll_array);
  1123. qnetd_cluster_list_free(&instance->clusters);
  1124. qnetd_client_list_free(&instance->clients);
  1125. return (0);
  1126. }
  1127. static void
  1128. signal_int_handler(int sig)
  1129. {
  1130. qnetd_log(LOG_DEBUG, "SIGINT received - closing server socket");
  1131. PR_Close(global_server_socket);
  1132. }
  1133. static void
  1134. signal_term_handler(int sig)
  1135. {
  1136. qnetd_log(LOG_DEBUG, "SIGTERM received - closing server socket");
  1137. PR_Close(global_server_socket);
  1138. }
  1139. static void
  1140. signal_handlers_register(void)
  1141. {
  1142. struct sigaction act;
  1143. act.sa_handler = signal_int_handler;
  1144. sigemptyset(&act.sa_mask);
  1145. act.sa_flags = SA_RESTART;
  1146. sigaction(SIGINT, &act, NULL);
  1147. act.sa_handler = signal_term_handler;
  1148. sigemptyset(&act.sa_mask);
  1149. act.sa_flags = SA_RESTART;
  1150. sigaction(SIGTERM, &act, NULL);
  1151. }
  1152. static void
  1153. usage(void)
  1154. {
  1155. printf("usage: %s [-df] [-l listen_addr] [-p listen_port] [-s tls]\n", QNETD_PROGRAM_NAME);
  1156. printf("%14s[-c client_cert_required] [-m max_clients]\n", "");
  1157. }
  1158. static void
  1159. cli_parse(int argc, char * const argv[], char **host_addr, uint16_t *host_port, int *foreground,
  1160. int *debug_log, enum tlv_tls_supported *tls_supported, int *client_cert_required,
  1161. size_t *max_clients)
  1162. {
  1163. int ch;
  1164. char *ep;
  1165. long long int tmpll;
  1166. *host_addr = NULL;
  1167. *host_port = QNETD_DEFAULT_HOST_PORT;
  1168. *foreground = 0;
  1169. *debug_log = 0;
  1170. *tls_supported = QNETD_DEFAULT_TLS_SUPPORTED;
  1171. *client_cert_required = QNETD_DEFAULT_TLS_CLIENT_CERT_REQUIRED;
  1172. *max_clients = QNETD_DEFAULT_MAX_CLIENTS;
  1173. while ((ch = getopt(argc, argv, "fdc:l:m:p:s:")) != -1) {
  1174. switch (ch) {
  1175. case 'f':
  1176. *foreground = 1;
  1177. break;
  1178. case 'd':
  1179. *debug_log = 1;
  1180. break;
  1181. case 'c':
  1182. if ((*client_cert_required = utils_parse_bool_str(optarg)) == -1) {
  1183. errx(1, "client_cert_required should be on/yes/1, off/no/0");
  1184. }
  1185. break;
  1186. case 'l':
  1187. *host_addr = strdup(optarg);
  1188. break;
  1189. case 'm':
  1190. errno = 0;
  1191. tmpll = strtoll(optarg, &ep, 10);
  1192. if (tmpll < 0 || errno != 0 || *ep != '\0') {
  1193. errx(1, "max clients value %s is invalid", optarg);
  1194. }
  1195. *max_clients = (size_t)tmpll;
  1196. break;
  1197. case 'p':
  1198. *host_port = strtol(optarg, &ep, 10);
  1199. if (*host_port <= 0 || *host_port > ((uint16_t)~0) || *ep != '\0') {
  1200. errx(1, "host port must be in range 0-65535");
  1201. }
  1202. break;
  1203. case 's':
  1204. if (strcasecmp(optarg, "on") == 0) {
  1205. *tls_supported = QNETD_DEFAULT_TLS_SUPPORTED;
  1206. } else if (strcasecmp(optarg, "off") == 0) {
  1207. *tls_supported = TLV_TLS_UNSUPPORTED;
  1208. } else if (strcasecmp(optarg, "req") == 0) {
  1209. *tls_supported = TLV_TLS_REQUIRED;
  1210. } else {
  1211. errx(1, "tls must be one of on, off, req");
  1212. }
  1213. break;
  1214. case '?':
  1215. usage();
  1216. exit(1);
  1217. break;
  1218. }
  1219. }
  1220. }
  1221. int
  1222. main(int argc, char *argv[])
  1223. {
  1224. struct qnetd_instance instance;
  1225. char *host_addr;
  1226. uint16_t host_port;
  1227. int foreground;
  1228. int debug_log;
  1229. enum tlv_tls_supported tls_supported;
  1230. int client_cert_required;
  1231. size_t max_clients;
  1232. cli_parse(argc, argv, &host_addr, &host_port, &foreground, &debug_log, &tls_supported,
  1233. &client_cert_required, &max_clients);
  1234. if (foreground) {
  1235. qnetd_log_init(QNETD_LOG_TARGET_STDERR);
  1236. } else {
  1237. qnetd_log_init(QNETD_LOG_TARGET_SYSLOG);
  1238. }
  1239. qnetd_log_set_debug(debug_log);
  1240. if (nss_sock_init_nss((tls_supported != TLV_TLS_UNSUPPORTED ?
  1241. (char *)QNETD_NSS_DB_DIR : NULL)) != 0) {
  1242. qnetd_err_nss();
  1243. }
  1244. if (SSL_ConfigServerSessionIDCache(0, 0, 0, NULL) != SECSuccess) {
  1245. qnetd_err_nss();
  1246. }
  1247. if (qnetd_instance_init(&instance, QNETD_MAX_CLIENT_RECEIVE_SIZE,
  1248. QNETD_MAX_CLIENT_SEND_BUFFERS, QNETD_MAX_CLIENT_SEND_SIZE,
  1249. tls_supported, client_cert_required, max_clients) == -1) {
  1250. errx(1, "Can't initialize qnetd");
  1251. }
  1252. instance.host_addr = host_addr;
  1253. instance.host_port = host_port;
  1254. if (qnetd_instance_init_certs(&instance) == -1) {
  1255. qnetd_err_nss();
  1256. }
  1257. instance.server.socket = nss_sock_create_listen_socket(instance.host_addr,
  1258. instance.host_port, PR_AF_INET6);
  1259. if (instance.server.socket == NULL) {
  1260. qnetd_err_nss();
  1261. }
  1262. if (nss_sock_set_nonblocking(instance.server.socket) != 0) {
  1263. qnetd_err_nss();
  1264. }
  1265. if (PR_Listen(instance.server.socket, QNETD_LISTEN_BACKLOG) != PR_SUCCESS) {
  1266. qnetd_err_nss();
  1267. }
  1268. global_server_socket = instance.server.socket;
  1269. signal_handlers_register();
  1270. algorithms_register();
  1271. /*
  1272. * MAIN LOOP
  1273. */
  1274. while (qnetd_poll(&instance) == 0) {
  1275. }
  1276. /*
  1277. * Cleanup
  1278. */
  1279. CERT_DestroyCertificate(instance.server.cert);
  1280. SECKEY_DestroyPrivateKey(instance.server.private_key);
  1281. SSL_ClearSessionCache();
  1282. SSL_ShutdownServerSessionIDCache();
  1283. qnetd_instance_destroy(&instance);
  1284. if (NSS_Shutdown() != SECSuccess) {
  1285. qnetd_warn_nss();
  1286. }
  1287. if (PR_Cleanup() != PR_SUCCESS) {
  1288. qnetd_warn_nss();
  1289. }
  1290. qnetd_log_close();
  1291. return (0);
  1292. }