corosync-qnetd.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606
  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. client->cluster_list = &instance->clusters;
  376. }
  377. }
  378. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  379. reply_error_code = qnetd_algorithm_client_init(client);
  380. }
  381. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  382. /*
  383. * Correct init received
  384. */
  385. client->init_received = 1;
  386. }
  387. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  388. if (send_buffer == NULL) {
  389. qnetd_log(LOG_ERR, "Can't alloc init reply msg from list. "
  390. "Disconnecting client connection.");
  391. return (-1);
  392. }
  393. if (msg_create_init_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  394. reply_error_code,
  395. supported_msgs, no_supported_msgs, supported_opts, no_supported_opts,
  396. instance->max_client_receive_size, instance->max_client_send_size,
  397. qnetd_static_supported_decision_algorithms,
  398. QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE) == -1) {
  399. qnetd_log(LOG_ERR, "Can't alloc init reply msg. Disconnecting client connection.");
  400. return (-1);
  401. }
  402. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  403. return (0);
  404. }
  405. static int
  406. qnetd_client_msg_received_init_reply(struct qnetd_instance *instance, struct qnetd_client *client,
  407. const struct msg_decoded *msg)
  408. {
  409. return (qnetd_client_msg_received_unexpected_msg(client, msg, "init reply"));
  410. }
  411. static int
  412. qnetd_client_msg_received_set_option_reply(struct qnetd_instance *instance,
  413. struct qnetd_client *client, const struct msg_decoded *msg)
  414. {
  415. return (qnetd_client_msg_received_unexpected_msg(client, msg, "set option reply"));
  416. }
  417. static int
  418. qnetd_client_msg_received_set_option(struct qnetd_instance *instance, struct qnetd_client *client,
  419. const struct msg_decoded *msg)
  420. {
  421. int res;
  422. struct send_buffer_list_entry *send_buffer;
  423. if ((res = qnetd_client_check_tls(instance, client, msg)) != 0) {
  424. return (res == -1 ? -1 : 0);
  425. }
  426. if (!client->init_received) {
  427. qnetd_log(LOG_ERR, "Received set option message before init message. "
  428. "Sending error reply.");
  429. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  430. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  431. return (-1);
  432. }
  433. return (0);
  434. }
  435. if (msg->heartbeat_interval_set) {
  436. /*
  437. * Check if heartbeat interval is valid
  438. */
  439. if (msg->heartbeat_interval != 0 &&
  440. (msg->heartbeat_interval < QNETD_HEARTBEAT_INTERVAL_MIN ||
  441. msg->heartbeat_interval > QNETD_HEARTBEAT_INTERVAL_MAX)) {
  442. qnetd_log(LOG_ERR, "Client requested invalid heartbeat interval %u. "
  443. "Sending error reply.", msg->heartbeat_interval);
  444. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  445. TLV_REPLY_ERROR_CODE_INVALID_HEARTBEAT_INTERVAL) != 0) {
  446. return (-1);
  447. }
  448. return (0);
  449. }
  450. client->heartbeat_interval = msg->heartbeat_interval;
  451. }
  452. if (msg->tie_breaker_set) {
  453. memcpy(&client->tie_breaker, &msg->tie_breaker, sizeof(msg->tie_breaker));
  454. }
  455. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  456. if (send_buffer == NULL) {
  457. qnetd_log(LOG_ERR, "Can't alloc set option reply msg from list. "
  458. "Disconnecting client connection.");
  459. return (-1);
  460. }
  461. if (msg_create_set_option_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  462. client->decision_algorithm, client->heartbeat_interval,
  463. msg->tie_breaker_set, &msg->tie_breaker) == -1) {
  464. qnetd_log(LOG_ERR, "Can't alloc set option reply msg. "
  465. "Disconnecting client connection.");
  466. return (-1);
  467. }
  468. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  469. return (0);
  470. }
  471. static int
  472. qnetd_client_msg_received_echo_reply(struct qnetd_instance *instance, struct qnetd_client *client,
  473. const struct msg_decoded *msg)
  474. {
  475. return (qnetd_client_msg_received_unexpected_msg(client, msg, "echo reply"));
  476. }
  477. static int
  478. qnetd_client_msg_received_echo_request(struct qnetd_instance *instance, struct qnetd_client *client,
  479. const struct msg_decoded *msg, const struct dynar *msg_orig)
  480. {
  481. int res;
  482. struct send_buffer_list_entry *send_buffer;
  483. if ((res = qnetd_client_check_tls(instance, client, msg)) != 0) {
  484. return (res == -1 ? -1 : 0);
  485. }
  486. if (!client->init_received) {
  487. qnetd_log(LOG_ERR, "Received echo request before init message. "
  488. "Sending error reply.");
  489. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  490. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  491. return (-1);
  492. }
  493. return (0);
  494. }
  495. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  496. if (send_buffer == NULL) {
  497. qnetd_log(LOG_ERR, "Can't alloc echo reply msg from list. "
  498. "Disconnecting client connection.");
  499. return (-1);
  500. }
  501. if (msg_create_echo_reply(&send_buffer->buffer, msg_orig) == -1) {
  502. qnetd_log(LOG_ERR, "Can't alloc echo reply msg. Disconnecting client connection.");
  503. return (-1);
  504. }
  505. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  506. return (0);
  507. }
  508. static int
  509. qnetd_client_msg_received_node_list(struct qnetd_instance *instance, struct qnetd_client *client,
  510. const struct msg_decoded *msg)
  511. {
  512. int res;
  513. struct send_buffer_list_entry *send_buffer;
  514. enum tlv_reply_error_code reply_error_code;
  515. enum tlv_vote result_vote;
  516. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  517. if ((res = qnetd_client_check_tls(instance, client, msg)) != 0) {
  518. return (res == -1 ? -1 : 0);
  519. }
  520. if (!client->init_received) {
  521. qnetd_log(LOG_ERR, "Received node list message before init message. "
  522. "Sending error reply.");
  523. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  524. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  525. return (-1);
  526. }
  527. return (0);
  528. }
  529. if (!msg->node_list_type_set) {
  530. qnetd_log(LOG_ERR, "Received node list message without node list type set. "
  531. "Sending error reply.");
  532. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  533. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  534. return (-1);
  535. }
  536. return (0);
  537. }
  538. if (!msg->seq_number_set) {
  539. qnetd_log(LOG_ERR, "Received node list message without seq number set. "
  540. "Sending error reply.");
  541. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  542. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  543. return (-1);
  544. }
  545. return (0);
  546. }
  547. switch (msg->node_list_type) {
  548. case TLV_NODE_LIST_TYPE_INITIAL_CONFIG:
  549. case TLV_NODE_LIST_TYPE_CHANGED_CONFIG:
  550. reply_error_code = qnetd_algorithm_config_node_list_received(client,
  551. msg->seq_number, msg->config_version_set, msg->config_version,
  552. &msg->nodes,
  553. (msg->node_list_type == TLV_NODE_LIST_TYPE_INITIAL_CONFIG),
  554. &result_vote);
  555. break;
  556. case TLV_NODE_LIST_TYPE_MEMBERSHIP:
  557. if (!msg->ring_id_set) {
  558. qnetd_log(LOG_ERR, "Received node list message without ring id number set. "
  559. "Sending error reply.");
  560. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  561. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  562. return (-1);
  563. }
  564. return (0);
  565. }
  566. reply_error_code = qnetd_algorithm_membership_node_list_received(client,
  567. msg->seq_number, &msg->ring_id, &msg->nodes, &result_vote);
  568. break;
  569. case TLV_NODE_LIST_TYPE_QUORUM:
  570. if (!msg->quorate_set) {
  571. qnetd_log(LOG_ERR, "Received quorum list message without quorate set. "
  572. "Sending error reply.");
  573. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  574. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  575. return (-1);
  576. }
  577. return (0);
  578. }
  579. reply_error_code = qnetd_algorithm_quorum_node_list_received(client,
  580. msg->seq_number,msg->quorate, &msg->nodes, &result_vote);
  581. break;
  582. default:
  583. errx(1, "qnetd_client_msg_received_node_list fatal error. "
  584. "Unhandled node_list_type");
  585. break;
  586. }
  587. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  588. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  589. "Sending error reply.");
  590. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  591. reply_error_code) != 0) {
  592. return (-1);
  593. }
  594. return (0);
  595. }
  596. /*
  597. * Store node list for future use
  598. */
  599. switch (msg->node_list_type) {
  600. case TLV_NODE_LIST_TYPE_INITIAL_CONFIG:
  601. case TLV_NODE_LIST_TYPE_CHANGED_CONFIG:
  602. node_list_free(&client->configuration_node_list);
  603. if (node_list_clone(&client->configuration_node_list, &msg->nodes) == -1) {
  604. qnetd_log(LOG_ERR, "Can't alloc config node list clone. "
  605. "Disconnecting client connection.");
  606. return (-1);
  607. }
  608. break;
  609. case TLV_NODE_LIST_TYPE_MEMBERSHIP:
  610. node_list_free(&client->last_membership_node_list);
  611. if (node_list_clone(&client->last_membership_node_list, &msg->nodes) == -1) {
  612. qnetd_log(LOG_ERR, "Can't alloc membership node list clone. "
  613. "Disconnecting client connection.");
  614. return (-1);
  615. }
  616. break;
  617. case TLV_NODE_LIST_TYPE_QUORUM:
  618. node_list_free(&client->last_quorum_node_list);
  619. if (node_list_clone(&client->last_quorum_node_list, &msg->nodes) == -1) {
  620. qnetd_log(LOG_ERR, "Can't alloc quorum node list clone. "
  621. "Disconnecting client connection.");
  622. return (-1);
  623. }
  624. break;
  625. default:
  626. errx(1, "qnetd_client_msg_received_node_list fatal error. "
  627. "Unhandled node_list_type");
  628. break;
  629. }
  630. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  631. if (send_buffer == NULL) {
  632. qnetd_log(LOG_ERR, "Can't alloc node list reply msg from list. "
  633. "Disconnecting client connection.");
  634. return (-1);
  635. }
  636. if (msg_create_node_list_reply(&send_buffer->buffer, msg->seq_number, result_vote) == -1) {
  637. qnetd_log(LOG_ERR, "Can't alloc node list reply msg. "
  638. "Disconnecting client connection.");
  639. return (-1);
  640. }
  641. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  642. return (0);
  643. }
  644. static int
  645. qnetd_client_msg_received_node_list_reply(struct qnetd_instance *instance,
  646. struct qnetd_client *client, const struct msg_decoded *msg)
  647. {
  648. return (qnetd_client_msg_received_unexpected_msg(client, msg, "node list reply"));
  649. }
  650. static int
  651. qnetd_client_msg_received_ask_for_vote(struct qnetd_instance *instance, struct qnetd_client *client,
  652. const struct msg_decoded *msg)
  653. {
  654. int res;
  655. struct send_buffer_list_entry *send_buffer;
  656. enum tlv_reply_error_code reply_error_code;
  657. enum tlv_vote result_vote;
  658. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  659. if ((res = qnetd_client_check_tls(instance, client, msg)) != 0) {
  660. return (res == -1 ? -1 : 0);
  661. }
  662. if (!client->init_received) {
  663. qnetd_log(LOG_ERR, "Received ask for vote message before init message. "
  664. "Sending error reply.");
  665. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  666. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  667. return (-1);
  668. }
  669. return (0);
  670. }
  671. if (!msg->seq_number_set) {
  672. qnetd_log(LOG_ERR, "Received ask for vote message without seq number set. "
  673. "Sending error reply.");
  674. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  675. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  676. return (-1);
  677. }
  678. return (0);
  679. }
  680. reply_error_code = qnetd_algorithm_ask_for_vote_received(client, msg->seq_number,
  681. &result_vote);
  682. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  683. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  684. "Sending error reply.");
  685. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  686. reply_error_code) != 0) {
  687. return (-1);
  688. }
  689. return (0);
  690. }
  691. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  692. if (send_buffer == NULL) {
  693. qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg from list. "
  694. "Disconnecting client connection.");
  695. return (-1);
  696. }
  697. if (msg_create_ask_for_vote_reply(&send_buffer->buffer, msg->seq_number,
  698. result_vote) == -1) {
  699. qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg. "
  700. "Disconnecting client connection.");
  701. return (-1);
  702. }
  703. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  704. return (0);
  705. }
  706. static int
  707. qnetd_client_msg_received_ask_for_vote_reply(struct qnetd_instance *instance,
  708. struct qnetd_client *client, const struct msg_decoded *msg)
  709. {
  710. return (qnetd_client_msg_received_unexpected_msg(client, msg, "ask for vote reply"));
  711. }
  712. static int
  713. qnetd_client_msg_received_vote_info(struct qnetd_instance *instance, struct qnetd_client *client,
  714. const struct msg_decoded *msg)
  715. {
  716. return (qnetd_client_msg_received_unexpected_msg(client, msg, "vote info"));
  717. }
  718. static int
  719. qnetd_client_msg_received_vote_info_reply(struct qnetd_instance *instance,
  720. struct qnetd_client *client, const struct msg_decoded *msg)
  721. {
  722. int res;
  723. enum tlv_reply_error_code reply_error_code;
  724. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  725. if ((res = qnetd_client_check_tls(instance, client, msg)) != 0) {
  726. return (res == -1 ? -1 : 0);
  727. }
  728. if (!client->init_received) {
  729. qnetd_log(LOG_ERR, "Received vote info reply before init message. "
  730. "Sending error reply.");
  731. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  732. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  733. return (-1);
  734. }
  735. return (0);
  736. }
  737. if (!msg->seq_number_set) {
  738. qnetd_log(LOG_ERR, "Received vote info reply message without seq number set. "
  739. "Sending error reply.");
  740. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  741. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  742. return (-1);
  743. }
  744. return (0);
  745. }
  746. reply_error_code = qnetd_algorithm_vote_info_reply_received(client, msg->seq_number);
  747. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  748. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  749. "Sending error reply.");
  750. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  751. reply_error_code) != 0) {
  752. return (-1);
  753. }
  754. return (0);
  755. }
  756. return (0);
  757. }
  758. static int
  759. qnetd_client_msg_received(struct qnetd_instance *instance, struct qnetd_client *client)
  760. {
  761. struct msg_decoded msg;
  762. int res;
  763. int ret_val;
  764. msg_decoded_init(&msg);
  765. res = msg_decode(&client->receive_buffer, &msg);
  766. if (res != 0) {
  767. /*
  768. * Error occurred. Send server error.
  769. */
  770. qnetd_client_log_msg_decode_error(res);
  771. qnetd_log(LOG_INFO, "Sending back error message");
  772. if (qnetd_client_send_err(client, msg.seq_number_set, msg.seq_number,
  773. TLV_REPLY_ERROR_CODE_ERROR_DECODING_MSG) != 0) {
  774. return (-1);
  775. }
  776. return (0);
  777. }
  778. ret_val = 0;
  779. switch (msg.type) {
  780. case MSG_TYPE_PREINIT:
  781. ret_val = qnetd_client_msg_received_preinit(instance, client, &msg);
  782. break;
  783. case MSG_TYPE_PREINIT_REPLY:
  784. ret_val = qnetd_client_msg_received_preinit_reply(instance, client, &msg);
  785. break;
  786. case MSG_TYPE_STARTTLS:
  787. ret_val = qnetd_client_msg_received_starttls(instance, client, &msg);
  788. break;
  789. case MSG_TYPE_INIT:
  790. ret_val = qnetd_client_msg_received_init(instance, client, &msg);
  791. break;
  792. case MSG_TYPE_INIT_REPLY:
  793. ret_val = qnetd_client_msg_received_init_reply(instance, client, &msg);
  794. break;
  795. case MSG_TYPE_SERVER_ERROR:
  796. ret_val = qnetd_client_msg_received_server_error(instance, client, &msg);
  797. break;
  798. case MSG_TYPE_SET_OPTION:
  799. ret_val = qnetd_client_msg_received_set_option(instance, client, &msg);
  800. break;
  801. case MSG_TYPE_SET_OPTION_REPLY:
  802. ret_val = qnetd_client_msg_received_set_option_reply(instance, client, &msg);
  803. break;
  804. case MSG_TYPE_ECHO_REQUEST:
  805. ret_val = qnetd_client_msg_received_echo_request(instance, client, &msg,
  806. &client->receive_buffer);
  807. break;
  808. case MSG_TYPE_ECHO_REPLY:
  809. ret_val = qnetd_client_msg_received_echo_reply(instance, client, &msg);
  810. break;
  811. case MSG_TYPE_NODE_LIST:
  812. ret_val = qnetd_client_msg_received_node_list(instance, client, &msg);
  813. break;
  814. case MSG_TYPE_NODE_LIST_REPLY:
  815. ret_val = qnetd_client_msg_received_node_list_reply(instance, client, &msg);
  816. break;
  817. case MSG_TYPE_ASK_FOR_VOTE:
  818. ret_val = qnetd_client_msg_received_ask_for_vote(instance, client, &msg);
  819. break;
  820. case MSG_TYPE_ASK_FOR_VOTE_REPLY:
  821. ret_val = qnetd_client_msg_received_ask_for_vote_reply(instance, client, &msg);
  822. break;
  823. case MSG_TYPE_VOTE_INFO:
  824. ret_val = qnetd_client_msg_received_vote_info(instance, client, &msg);
  825. break;
  826. case MSG_TYPE_VOTE_INFO_REPLY:
  827. ret_val = qnetd_client_msg_received_vote_info_reply(instance, client, &msg);
  828. break;
  829. default:
  830. qnetd_log(LOG_ERR, "Unsupported message %u received from client. "
  831. "Sending back error message", msg.type);
  832. if (qnetd_client_send_err(client, msg.seq_number_set, msg.seq_number,
  833. TLV_REPLY_ERROR_CODE_UNSUPPORTED_MESSAGE) != 0) {
  834. ret_val = -1;
  835. }
  836. break;
  837. }
  838. msg_decoded_destroy(&msg);
  839. return (ret_val);
  840. }
  841. static int
  842. qnetd_client_net_write_finished(struct qnetd_instance *instance, struct qnetd_client *client)
  843. {
  844. /*
  845. * Callback is currently unused
  846. */
  847. return (0);
  848. }
  849. static int
  850. qnetd_client_net_write(struct qnetd_instance *instance, struct qnetd_client *client)
  851. {
  852. int res;
  853. struct send_buffer_list_entry *send_buffer;
  854. send_buffer = send_buffer_list_get_active(&client->send_buffer_list);
  855. if (send_buffer == NULL) {
  856. qnetd_log_nss(LOG_CRIT, "send_buffer_list_get_active returned NULL");
  857. return (-1);
  858. }
  859. res = msgio_write(client->socket, &send_buffer->buffer,
  860. &send_buffer->msg_already_sent_bytes);
  861. if (res == 1) {
  862. send_buffer_list_delete(&client->send_buffer_list, send_buffer);
  863. if (qnetd_client_net_write_finished(instance, client) == -1) {
  864. return (-1);
  865. }
  866. }
  867. if (res == -1) {
  868. qnetd_log_nss(LOG_CRIT, "PR_Send returned 0");
  869. return (-1);
  870. }
  871. if (res == -2) {
  872. qnetd_log_nss(LOG_ERR, "Unhandled error when sending message to client");
  873. return (-1);
  874. }
  875. return (0);
  876. }
  877. /*
  878. * -1 means end of connection (EOF) or some other unhandled error. 0 = success
  879. */
  880. static int
  881. qnetd_client_net_read(struct qnetd_instance *instance, struct qnetd_client *client)
  882. {
  883. int res;
  884. int ret_val;
  885. int orig_skipping_msg;
  886. orig_skipping_msg = client->skipping_msg;
  887. res = msgio_read(client->socket, &client->receive_buffer,
  888. &client->msg_already_received_bytes, &client->skipping_msg);
  889. if (!orig_skipping_msg && client->skipping_msg) {
  890. qnetd_log(LOG_DEBUG, "msgio_read set skipping_msg");
  891. }
  892. ret_val = 0;
  893. switch (res) {
  894. case 0:
  895. /*
  896. * Partial read
  897. */
  898. break;
  899. case -1:
  900. qnetd_log(LOG_DEBUG, "Client closed connection");
  901. ret_val = -1;
  902. break;
  903. case -2:
  904. qnetd_log_nss(LOG_ERR, "Unhandled error when reading from client. "
  905. "Disconnecting client");
  906. ret_val = -1;
  907. break;
  908. case -3:
  909. qnetd_log(LOG_ERR, "Can't store message header from client. Disconnecting client");
  910. ret_val = -1;
  911. break;
  912. case -4:
  913. qnetd_log(LOG_ERR, "Can't store message from client. Skipping message");
  914. client->skipping_msg_reason = TLV_REPLY_ERROR_CODE_ERROR_DECODING_MSG;
  915. break;
  916. case -5:
  917. qnetd_log(LOG_WARNING, "Client sent unsupported msg type %u. Skipping message",
  918. msg_get_type(&client->receive_buffer));
  919. client->skipping_msg_reason = TLV_REPLY_ERROR_CODE_UNSUPPORTED_MESSAGE;
  920. break;
  921. case -6:
  922. qnetd_log(LOG_WARNING,
  923. "Client wants to send too long message %u bytes. Skipping message",
  924. msg_get_len(&client->receive_buffer));
  925. client->skipping_msg_reason = TLV_REPLY_ERROR_CODE_MESSAGE_TOO_LONG;
  926. break;
  927. case 1:
  928. /*
  929. * Full message received / skipped
  930. */
  931. if (!client->skipping_msg) {
  932. if (qnetd_client_msg_received(instance, client) == -1) {
  933. ret_val = -1;
  934. }
  935. } else {
  936. if (qnetd_client_send_err(client, 0, 0, client->skipping_msg_reason) != 0) {
  937. ret_val = -1;
  938. }
  939. }
  940. client->skipping_msg = 0;
  941. client->skipping_msg_reason = TLV_REPLY_ERROR_CODE_NO_ERROR;
  942. client->msg_already_received_bytes = 0;
  943. dynar_clean(&client->receive_buffer);
  944. break;
  945. default:
  946. errx(1, "Unhandled msgio_read error %d\n", res);
  947. break;
  948. }
  949. return (ret_val);
  950. }
  951. static int
  952. qnetd_client_accept(struct qnetd_instance *instance)
  953. {
  954. PRNetAddr client_addr;
  955. PRFileDesc *client_socket;
  956. struct qnetd_client *client;
  957. if ((client_socket = PR_Accept(instance->server.socket, &client_addr,
  958. PR_INTERVAL_NO_TIMEOUT)) == NULL) {
  959. qnetd_log_nss(LOG_ERR, "Can't accept connection");
  960. return (-1);
  961. }
  962. if (nss_sock_set_nonblocking(client_socket) != 0) {
  963. qnetd_log_nss(LOG_ERR, "Can't set client socket to non blocking mode");
  964. PR_Close(client_socket);
  965. return (-1);
  966. }
  967. if (instance->max_clients != 0 &&
  968. qnetd_client_list_no_clients(&instance->clients) >= instance->max_clients) {
  969. qnetd_log(LOG_ERR, "Maximum clients reached. Not accepting connection");
  970. PR_Close(client_socket);
  971. return (-1);
  972. }
  973. client = qnetd_client_list_add(&instance->clients, client_socket, &client_addr,
  974. instance->max_client_receive_size, instance->max_client_send_buffers,
  975. instance->max_client_send_size);
  976. if (client == NULL) {
  977. qnetd_log(LOG_ERR, "Can't add client to list");
  978. PR_Close(client_socket);
  979. return (-2);
  980. }
  981. return (0);
  982. }
  983. static void
  984. qnetd_client_disconnect(struct qnetd_instance *instance, struct qnetd_client *client,
  985. int server_going_down)
  986. {
  987. qnetd_algorithm_client_disconnect(client, server_going_down);
  988. PR_Close(client->socket);
  989. if (client->cluster != NULL) {
  990. qnetd_cluster_list_del_client(&instance->clusters, client->cluster, client);
  991. }
  992. qnetd_client_list_del(&instance->clients, client);
  993. }
  994. static int
  995. qnetd_poll(struct qnetd_instance *instance)
  996. {
  997. struct qnetd_client *client;
  998. struct qnetd_client *client_next;
  999. PRPollDesc *pfds;
  1000. PRInt32 poll_res;
  1001. int i;
  1002. int client_disconnect;
  1003. client = NULL;
  1004. client_disconnect = 0;
  1005. pfds = qnetd_poll_array_create_from_client_list(&instance->poll_array,
  1006. &instance->clients, instance->server.socket, PR_POLL_READ);
  1007. if (pfds == NULL) {
  1008. return (-1);
  1009. }
  1010. if ((poll_res = PR_Poll(pfds, qnetd_poll_array_size(&instance->poll_array),
  1011. PR_INTERVAL_NO_TIMEOUT)) > 0) {
  1012. /*
  1013. * Walk thru pfds array and process events
  1014. */
  1015. for (i = 0; i < qnetd_poll_array_size(&instance->poll_array); i++) {
  1016. /*
  1017. * Also traverse clients list
  1018. */
  1019. if (i > 0) {
  1020. if (i == 1) {
  1021. client = TAILQ_FIRST(&instance->clients);
  1022. client_next = TAILQ_NEXT(client, entries);
  1023. } else {
  1024. client = client_next;
  1025. client_next = TAILQ_NEXT(client, entries);
  1026. }
  1027. }
  1028. client_disconnect = 0;
  1029. if (!client_disconnect && pfds[i].out_flags & PR_POLL_READ) {
  1030. if (i == 0) {
  1031. qnetd_client_accept(instance);
  1032. } else {
  1033. if (qnetd_client_net_read(instance, client) == -1) {
  1034. client_disconnect = 1;
  1035. }
  1036. }
  1037. }
  1038. if (!client_disconnect && pfds[i].out_flags & PR_POLL_WRITE) {
  1039. if (i == 0) {
  1040. /*
  1041. * Poll write on listen socket -> fatal error
  1042. */
  1043. qnetd_log(LOG_CRIT, "POLL_WRITE on listening socket");
  1044. return (-1);
  1045. } else {
  1046. if (qnetd_client_net_write(instance, client) == -1) {
  1047. client_disconnect = 1;
  1048. }
  1049. }
  1050. }
  1051. if (!client_disconnect &&
  1052. pfds[i].out_flags &
  1053. (PR_POLL_ERR|PR_POLL_NVAL|PR_POLL_HUP|PR_POLL_EXCEPT)) {
  1054. if (i == 0) {
  1055. if (pfds[i].out_flags != PR_POLL_NVAL) {
  1056. /*
  1057. * Poll ERR on listening socket is fatal error.
  1058. * POLL_NVAL is used as a signal to quit poll loop.
  1059. */
  1060. qnetd_log(LOG_CRIT, "POLL_ERR (%u) on listening "
  1061. "socket", pfds[i].out_flags);
  1062. } else {
  1063. qnetd_log(LOG_DEBUG, "Listening socket is closed");
  1064. }
  1065. return (-1);
  1066. } else {
  1067. qnetd_log(LOG_DEBUG, "POLL_ERR (%u) on client socket. "
  1068. "Disconnecting.", pfds[i].out_flags);
  1069. client_disconnect = 1;
  1070. }
  1071. }
  1072. /*
  1073. * If client is scheduled for disconnect, disconnect it
  1074. */
  1075. if (client_disconnect) {
  1076. qnetd_client_disconnect(instance, client, 0);
  1077. }
  1078. }
  1079. }
  1080. return (0);
  1081. }
  1082. static int
  1083. qnetd_instance_init_certs(struct qnetd_instance *instance)
  1084. {
  1085. instance->server.cert = PK11_FindCertFromNickname(QNETD_CERT_NICKNAME, NULL);
  1086. if (instance->server.cert == NULL) {
  1087. return (-1);
  1088. }
  1089. instance->server.private_key = PK11_FindKeyByAnyCert(instance->server.cert, NULL);
  1090. if (instance->server.private_key == NULL) {
  1091. return (-1);
  1092. }
  1093. return (0);
  1094. }
  1095. static int
  1096. qnetd_instance_init(struct qnetd_instance *instance, size_t max_client_receive_size,
  1097. size_t max_client_send_buffers, size_t max_client_send_size,
  1098. enum tlv_tls_supported tls_supported, int tls_client_cert_required, size_t max_clients)
  1099. {
  1100. memset(instance, 0, sizeof(*instance));
  1101. qnetd_poll_array_init(&instance->poll_array);
  1102. qnetd_client_list_init(&instance->clients);
  1103. qnetd_cluster_list_init(&instance->clusters);
  1104. instance->max_client_receive_size = max_client_receive_size;
  1105. instance->max_client_send_buffers = max_client_send_buffers;
  1106. instance->max_client_send_size = max_client_send_size;
  1107. instance->tls_supported = tls_supported;
  1108. instance->tls_client_cert_required = tls_client_cert_required;
  1109. instance->max_clients = max_clients;
  1110. return (0);
  1111. }
  1112. static int
  1113. qnetd_instance_destroy(struct qnetd_instance *instance)
  1114. {
  1115. struct qnetd_client *client;
  1116. struct qnetd_client *client_next;
  1117. client = TAILQ_FIRST(&instance->clients);
  1118. while (client != NULL) {
  1119. client_next = TAILQ_NEXT(client, entries);
  1120. qnetd_client_disconnect(instance, client, 1);
  1121. client = client_next;
  1122. }
  1123. qnetd_poll_array_destroy(&instance->poll_array);
  1124. qnetd_cluster_list_free(&instance->clusters);
  1125. qnetd_client_list_free(&instance->clients);
  1126. return (0);
  1127. }
  1128. static void
  1129. signal_int_handler(int sig)
  1130. {
  1131. qnetd_log(LOG_DEBUG, "SIGINT received - closing server socket");
  1132. PR_Close(global_server_socket);
  1133. }
  1134. static void
  1135. signal_term_handler(int sig)
  1136. {
  1137. qnetd_log(LOG_DEBUG, "SIGTERM received - closing server socket");
  1138. PR_Close(global_server_socket);
  1139. }
  1140. static void
  1141. signal_handlers_register(void)
  1142. {
  1143. struct sigaction act;
  1144. act.sa_handler = signal_int_handler;
  1145. sigemptyset(&act.sa_mask);
  1146. act.sa_flags = SA_RESTART;
  1147. sigaction(SIGINT, &act, NULL);
  1148. act.sa_handler = signal_term_handler;
  1149. sigemptyset(&act.sa_mask);
  1150. act.sa_flags = SA_RESTART;
  1151. sigaction(SIGTERM, &act, NULL);
  1152. }
  1153. static void
  1154. usage(void)
  1155. {
  1156. printf("usage: %s [-df] [-l listen_addr] [-p listen_port] [-s tls]\n", QNETD_PROGRAM_NAME);
  1157. printf("%14s[-c client_cert_required] [-m max_clients]\n", "");
  1158. }
  1159. static void
  1160. cli_parse(int argc, char * const argv[], char **host_addr, uint16_t *host_port, int *foreground,
  1161. int *debug_log, enum tlv_tls_supported *tls_supported, int *client_cert_required,
  1162. size_t *max_clients)
  1163. {
  1164. int ch;
  1165. char *ep;
  1166. long long int tmpll;
  1167. *host_addr = NULL;
  1168. *host_port = QNETD_DEFAULT_HOST_PORT;
  1169. *foreground = 0;
  1170. *debug_log = 0;
  1171. *tls_supported = QNETD_DEFAULT_TLS_SUPPORTED;
  1172. *client_cert_required = QNETD_DEFAULT_TLS_CLIENT_CERT_REQUIRED;
  1173. *max_clients = QNETD_DEFAULT_MAX_CLIENTS;
  1174. while ((ch = getopt(argc, argv, "fdc:l:m:p:s:")) != -1) {
  1175. switch (ch) {
  1176. case 'f':
  1177. *foreground = 1;
  1178. break;
  1179. case 'd':
  1180. *debug_log = 1;
  1181. break;
  1182. case 'c':
  1183. if ((*client_cert_required = utils_parse_bool_str(optarg)) == -1) {
  1184. errx(1, "client_cert_required should be on/yes/1, off/no/0");
  1185. }
  1186. break;
  1187. case 'l':
  1188. *host_addr = strdup(optarg);
  1189. break;
  1190. case 'm':
  1191. errno = 0;
  1192. tmpll = strtoll(optarg, &ep, 10);
  1193. if (tmpll < 0 || errno != 0 || *ep != '\0') {
  1194. errx(1, "max clients value %s is invalid", optarg);
  1195. }
  1196. *max_clients = (size_t)tmpll;
  1197. break;
  1198. case 'p':
  1199. *host_port = strtol(optarg, &ep, 10);
  1200. if (*host_port <= 0 || *host_port > ((uint16_t)~0) || *ep != '\0') {
  1201. errx(1, "host port must be in range 0-65535");
  1202. }
  1203. break;
  1204. case 's':
  1205. if (strcasecmp(optarg, "on") == 0) {
  1206. *tls_supported = QNETD_DEFAULT_TLS_SUPPORTED;
  1207. } else if (strcasecmp(optarg, "off") == 0) {
  1208. *tls_supported = TLV_TLS_UNSUPPORTED;
  1209. } else if (strcasecmp(optarg, "req") == 0) {
  1210. *tls_supported = TLV_TLS_REQUIRED;
  1211. } else {
  1212. errx(1, "tls must be one of on, off, req");
  1213. }
  1214. break;
  1215. case '?':
  1216. usage();
  1217. exit(1);
  1218. break;
  1219. }
  1220. }
  1221. }
  1222. int
  1223. main(int argc, char *argv[])
  1224. {
  1225. struct qnetd_instance instance;
  1226. char *host_addr;
  1227. uint16_t host_port;
  1228. int foreground;
  1229. int debug_log;
  1230. enum tlv_tls_supported tls_supported;
  1231. int client_cert_required;
  1232. size_t max_clients;
  1233. cli_parse(argc, argv, &host_addr, &host_port, &foreground, &debug_log, &tls_supported,
  1234. &client_cert_required, &max_clients);
  1235. if (foreground) {
  1236. qnetd_log_init(QNETD_LOG_TARGET_STDERR);
  1237. } else {
  1238. qnetd_log_init(QNETD_LOG_TARGET_SYSLOG);
  1239. }
  1240. qnetd_log_set_debug(debug_log);
  1241. if (nss_sock_init_nss((tls_supported != TLV_TLS_UNSUPPORTED ?
  1242. (char *)QNETD_NSS_DB_DIR : NULL)) != 0) {
  1243. qnetd_err_nss();
  1244. }
  1245. if (SSL_ConfigServerSessionIDCache(0, 0, 0, NULL) != SECSuccess) {
  1246. qnetd_err_nss();
  1247. }
  1248. if (qnetd_instance_init(&instance, QNETD_MAX_CLIENT_RECEIVE_SIZE,
  1249. QNETD_MAX_CLIENT_SEND_BUFFERS, QNETD_MAX_CLIENT_SEND_SIZE,
  1250. tls_supported, client_cert_required, max_clients) == -1) {
  1251. errx(1, "Can't initialize qnetd");
  1252. }
  1253. instance.host_addr = host_addr;
  1254. instance.host_port = host_port;
  1255. if (qnetd_instance_init_certs(&instance) == -1) {
  1256. qnetd_err_nss();
  1257. }
  1258. instance.server.socket = nss_sock_create_listen_socket(instance.host_addr,
  1259. instance.host_port, PR_AF_INET6);
  1260. if (instance.server.socket == NULL) {
  1261. qnetd_err_nss();
  1262. }
  1263. if (nss_sock_set_nonblocking(instance.server.socket) != 0) {
  1264. qnetd_err_nss();
  1265. }
  1266. if (PR_Listen(instance.server.socket, QNETD_LISTEN_BACKLOG) != PR_SUCCESS) {
  1267. qnetd_err_nss();
  1268. }
  1269. global_server_socket = instance.server.socket;
  1270. signal_handlers_register();
  1271. algorithms_register();
  1272. /*
  1273. * MAIN LOOP
  1274. */
  1275. while (qnetd_poll(&instance) == 0) {
  1276. }
  1277. /*
  1278. * Cleanup
  1279. */
  1280. CERT_DestroyCertificate(instance.server.cert);
  1281. SECKEY_DestroyPrivateKey(instance.server.private_key);
  1282. SSL_ClearSessionCache();
  1283. SSL_ShutdownServerSessionIDCache();
  1284. qnetd_instance_destroy(&instance);
  1285. if (NSS_Shutdown() != SECSuccess) {
  1286. qnetd_warn_nss();
  1287. }
  1288. if (PR_Cleanup() != PR_SUCCESS) {
  1289. qnetd_warn_nss();
  1290. }
  1291. qnetd_log_close();
  1292. return (0);
  1293. }