corosync-qnetd.c 39 KB

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