corosync-qnetd.c 41 KB

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