corosync-qnetd.c 39 KB

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