qnetd-client-msg-received.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949
  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 <sys/types.h>
  35. #include "qnetd-algorithm.h"
  36. #include "qnetd-instance.h"
  37. #include "qnetd-log.h"
  38. #include "qnetd-client-send.h"
  39. #include "msg.h"
  40. #include "nss-sock.h"
  41. #include "qnetd-client-msg-received.h"
  42. /*
  43. * 0 - Success
  44. * -1 - Disconnect client
  45. * -2 - Error reply sent, but no need to disconnect client
  46. */
  47. static int
  48. qnetd_client_msg_received_check_tls(struct qnetd_instance *instance, struct qnetd_client *client,
  49. const struct msg_decoded *msg)
  50. {
  51. int check_certificate;
  52. int tls_required;
  53. CERTCertificate *peer_cert;
  54. check_certificate = 0;
  55. tls_required = 0;
  56. switch (instance->tls_supported) {
  57. case TLV_TLS_UNSUPPORTED:
  58. tls_required = 0;
  59. check_certificate = 0;
  60. break;
  61. case TLV_TLS_SUPPORTED:
  62. tls_required = 0;
  63. if (client->tls_started && instance->tls_client_cert_required &&
  64. !client->tls_peer_certificate_verified) {
  65. check_certificate = 1;
  66. }
  67. break;
  68. case TLV_TLS_REQUIRED:
  69. tls_required = 1;
  70. if (instance->tls_client_cert_required && !client->tls_peer_certificate_verified) {
  71. check_certificate = 1;
  72. }
  73. break;
  74. default:
  75. qnetd_log(LOG_ERR, "Unhandled instance tls supported %u", instance->tls_supported);
  76. exit(1);
  77. break;
  78. }
  79. if (tls_required && !client->tls_started) {
  80. qnetd_log(LOG_ERR, "TLS is required but doesn't started yet. "
  81. "Sending back error message");
  82. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  83. TLV_REPLY_ERROR_CODE_TLS_REQUIRED) != 0) {
  84. return (-1);
  85. }
  86. return (-2);
  87. }
  88. if (check_certificate) {
  89. peer_cert = SSL_PeerCertificate(client->socket);
  90. if (peer_cert == NULL) {
  91. qnetd_log(LOG_ERR, "Client doesn't sent valid certificate. "
  92. "Disconnecting client");
  93. return (-1);
  94. }
  95. if (CERT_VerifyCertName(peer_cert, client->cluster_name) != SECSuccess) {
  96. qnetd_log(LOG_ERR, "Client doesn't sent certificate with valid CN. "
  97. "Disconnecting client");
  98. CERT_DestroyCertificate(peer_cert);
  99. return (-1);
  100. }
  101. CERT_DestroyCertificate(peer_cert);
  102. client->tls_peer_certificate_verified = 1;
  103. }
  104. return (0);
  105. }
  106. static int
  107. qnetd_client_msg_received_preinit(struct qnetd_instance *instance, struct qnetd_client *client,
  108. const struct msg_decoded *msg)
  109. {
  110. struct send_buffer_list_entry *send_buffer;
  111. if (msg->cluster_name == NULL) {
  112. qnetd_log(LOG_ERR, "Received preinit message without cluster name. "
  113. "Sending error reply.");
  114. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  115. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  116. return (-1);
  117. }
  118. return (0);
  119. }
  120. client->cluster_name = malloc(msg->cluster_name_len + 1);
  121. if (client->cluster_name == NULL) {
  122. qnetd_log(LOG_ERR, "Can't allocate cluster name. Sending error reply.");
  123. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  124. TLV_REPLY_ERROR_CODE_INTERNAL_ERROR) != 0) {
  125. return (-1);
  126. }
  127. return (0);
  128. }
  129. memset(client->cluster_name, 0, msg->cluster_name_len + 1);
  130. memcpy(client->cluster_name, msg->cluster_name, msg->cluster_name_len);
  131. client->cluster_name_len = msg->cluster_name_len;
  132. client->preinit_received = 1;
  133. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  134. if (send_buffer == NULL) {
  135. qnetd_log(LOG_ERR, "Can't alloc preinit reply msg from list. "
  136. "Disconnecting client connection.");
  137. return (-1);
  138. }
  139. if (msg_create_preinit_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  140. instance->tls_supported, instance->tls_client_cert_required) == 0) {
  141. qnetd_log(LOG_ERR, "Can't alloc preinit reply msg. "
  142. "Disconnecting client connection.");
  143. return (-1);
  144. };
  145. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  146. return (0);
  147. }
  148. static int
  149. qnetd_client_msg_received_unexpected_msg(struct qnetd_client *client,
  150. const struct msg_decoded *msg, const char *msg_str)
  151. {
  152. qnetd_log(LOG_ERR, "Received %s message. Sending back error message", msg_str);
  153. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  154. TLV_REPLY_ERROR_CODE_UNEXPECTED_MESSAGE) != 0) {
  155. return (-1);
  156. }
  157. return (0);
  158. }
  159. static int
  160. qnetd_client_msg_received_preinit_reply(struct qnetd_instance *instance,
  161. struct qnetd_client *client, const struct msg_decoded *msg)
  162. {
  163. return (qnetd_client_msg_received_unexpected_msg(client, msg, "preinit reply"));
  164. }
  165. static int
  166. qnetd_client_msg_received_starttls(struct qnetd_instance *instance, struct qnetd_client *client,
  167. const struct msg_decoded *msg)
  168. {
  169. PRFileDesc *new_pr_fd;
  170. if (!client->preinit_received) {
  171. qnetd_log(LOG_ERR, "Received starttls before preinit message. "
  172. "Sending error reply.");
  173. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  174. TLV_REPLY_ERROR_CODE_PREINIT_REQUIRED) != 0) {
  175. return (-1);
  176. }
  177. return (0);
  178. }
  179. if ((new_pr_fd = nss_sock_start_ssl_as_server(client->socket, instance->server.cert,
  180. instance->server.private_key, instance->tls_client_cert_required, 0, NULL)) == NULL) {
  181. qnetd_log_nss(LOG_ERR, "Can't start TLS. Disconnecting client.");
  182. return (-1);
  183. }
  184. client->tls_started = 1;
  185. client->tls_peer_certificate_verified = 0;
  186. client->socket = new_pr_fd;
  187. return (0);
  188. }
  189. static int
  190. qnetd_client_msg_received_server_error(struct qnetd_instance *instance, struct qnetd_client *client,
  191. const struct msg_decoded *msg)
  192. {
  193. return (qnetd_client_msg_received_unexpected_msg(client, msg, "server error"));
  194. }
  195. static int
  196. qnetd_client_msg_received_init(struct qnetd_instance *instance, struct qnetd_client *client,
  197. const struct msg_decoded *msg)
  198. {
  199. int res;
  200. size_t zi;
  201. enum msg_type *supported_msgs;
  202. size_t no_supported_msgs;
  203. enum tlv_opt_type *supported_opts;
  204. size_t no_supported_opts;
  205. struct send_buffer_list_entry *send_buffer;
  206. enum tlv_reply_error_code reply_error_code;
  207. struct qnetd_cluster *cluster;
  208. supported_msgs = NULL;
  209. supported_opts = NULL;
  210. no_supported_msgs = 0;
  211. no_supported_opts = 0;
  212. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  213. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  214. return (res == -1 ? -1 : 0);
  215. }
  216. if (!client->preinit_received) {
  217. qnetd_log(LOG_ERR, "Received init before preinit message. Sending error reply.");
  218. reply_error_code = TLV_REPLY_ERROR_CODE_PREINIT_REQUIRED;
  219. }
  220. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->node_id_set) {
  221. qnetd_log(LOG_ERR, "Received init message without node id set. "
  222. "Sending error reply.");
  223. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  224. } else {
  225. client->node_id_set = 1;
  226. client->node_id = msg->node_id;
  227. }
  228. if (msg->supported_messages != NULL) {
  229. /*
  230. * Client sent supported messages. For now this is ignored but in the future
  231. * this may be used to ensure backward compatibility.
  232. */
  233. /*
  234. for (i = 0; i < msg->no_supported_messages; i++) {
  235. qnetd_log(LOG_DEBUG, "Client supports %u message",
  236. (int)msg->supported_messages[i]);
  237. }
  238. */
  239. /*
  240. * Sent back supported messages
  241. */
  242. msg_get_supported_messages(&supported_msgs, &no_supported_msgs);
  243. }
  244. if (msg->supported_options != NULL) {
  245. /*
  246. * Client sent supported options. For now this is ignored but in the future
  247. * this may be used to ensure backward compatibility.
  248. */
  249. /*
  250. for (i = 0; i < msg->no_supported_options; i++) {
  251. qnetd_log(LOG_DEBUG, "Client supports %u option",
  252. (int)msg->supported_messages[i]);
  253. }
  254. */
  255. /*
  256. * Send back supported options
  257. */
  258. tlv_get_supported_options(&supported_opts, &no_supported_opts);
  259. }
  260. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->decision_algorithm_set) {
  261. qnetd_log(LOG_ERR, "Received init message without decision algorithm. "
  262. "Sending error reply.");
  263. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  264. } else {
  265. /*
  266. * Check if decision algorithm requested by client is supported
  267. */
  268. res = 0;
  269. for (zi = 0; zi < QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE && !res; zi++) {
  270. if (qnetd_static_supported_decision_algorithms[zi] ==
  271. msg->decision_algorithm) {
  272. res = 1;
  273. }
  274. }
  275. if (!res) {
  276. qnetd_log(LOG_ERR, "Client requested unsupported decision algorithm %u. "
  277. "Sending error reply.", msg->decision_algorithm);
  278. reply_error_code = TLV_REPLY_ERROR_CODE_UNSUPPORTED_DECISION_ALGORITHM;
  279. }
  280. client->decision_algorithm = msg->decision_algorithm;
  281. }
  282. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  283. cluster = qnetd_cluster_list_add_client(&instance->clusters, client);
  284. if (cluster == NULL) {
  285. qnetd_log(LOG_ERR, "Can't add client to cluster list. "
  286. "Sending error reply.");
  287. reply_error_code = TLV_REPLY_ERROR_CODE_INTERNAL_ERROR;
  288. } else {
  289. client->cluster = cluster;
  290. client->cluster_list = &instance->clusters;
  291. }
  292. }
  293. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  294. reply_error_code = qnetd_algorithm_client_init(client);
  295. }
  296. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  297. /*
  298. * Correct init received
  299. */
  300. client->init_received = 1;
  301. }
  302. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  303. if (send_buffer == NULL) {
  304. qnetd_log(LOG_ERR, "Can't alloc init reply msg from list. "
  305. "Disconnecting client connection.");
  306. return (-1);
  307. }
  308. if (msg_create_init_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  309. reply_error_code,
  310. supported_msgs, no_supported_msgs, supported_opts, no_supported_opts,
  311. instance->max_client_receive_size, instance->max_client_send_size,
  312. qnetd_static_supported_decision_algorithms,
  313. QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE) == -1) {
  314. qnetd_log(LOG_ERR, "Can't alloc init reply msg. Disconnecting client connection.");
  315. return (-1);
  316. }
  317. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  318. return (0);
  319. }
  320. static int
  321. qnetd_client_msg_received_init_reply(struct qnetd_instance *instance, struct qnetd_client *client,
  322. const struct msg_decoded *msg)
  323. {
  324. return (qnetd_client_msg_received_unexpected_msg(client, msg, "init reply"));
  325. }
  326. static int
  327. qnetd_client_msg_received_set_option_reply(struct qnetd_instance *instance,
  328. struct qnetd_client *client, const struct msg_decoded *msg)
  329. {
  330. return (qnetd_client_msg_received_unexpected_msg(client, msg, "set option reply"));
  331. }
  332. static int
  333. qnetd_client_msg_received_set_option(struct qnetd_instance *instance, struct qnetd_client *client,
  334. const struct msg_decoded *msg)
  335. {
  336. int res;
  337. struct send_buffer_list_entry *send_buffer;
  338. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  339. return (res == -1 ? -1 : 0);
  340. }
  341. if (!client->init_received) {
  342. qnetd_log(LOG_ERR, "Received set option message before init message. "
  343. "Sending error reply.");
  344. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  345. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  346. return (-1);
  347. }
  348. return (0);
  349. }
  350. if (msg->heartbeat_interval_set) {
  351. /*
  352. * Check if heartbeat interval is valid
  353. */
  354. if (msg->heartbeat_interval != 0 &&
  355. (msg->heartbeat_interval < QNETD_HEARTBEAT_INTERVAL_MIN ||
  356. msg->heartbeat_interval > QNETD_HEARTBEAT_INTERVAL_MAX)) {
  357. qnetd_log(LOG_ERR, "Client requested invalid heartbeat interval %u. "
  358. "Sending error reply.", msg->heartbeat_interval);
  359. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  360. TLV_REPLY_ERROR_CODE_INVALID_HEARTBEAT_INTERVAL) != 0) {
  361. return (-1);
  362. }
  363. return (0);
  364. }
  365. client->heartbeat_interval = msg->heartbeat_interval;
  366. }
  367. if (msg->tie_breaker_set) {
  368. memcpy(&client->tie_breaker, &msg->tie_breaker, sizeof(msg->tie_breaker));
  369. }
  370. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  371. if (send_buffer == NULL) {
  372. qnetd_log(LOG_ERR, "Can't alloc set option reply msg from list. "
  373. "Disconnecting client connection.");
  374. return (-1);
  375. }
  376. if (msg_create_set_option_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  377. client->decision_algorithm, client->heartbeat_interval,
  378. msg->tie_breaker_set, &msg->tie_breaker) == -1) {
  379. qnetd_log(LOG_ERR, "Can't alloc set option reply msg. "
  380. "Disconnecting client connection.");
  381. return (-1);
  382. }
  383. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  384. return (0);
  385. }
  386. static int
  387. qnetd_client_msg_received_echo_reply(struct qnetd_instance *instance, struct qnetd_client *client,
  388. const struct msg_decoded *msg)
  389. {
  390. return (qnetd_client_msg_received_unexpected_msg(client, msg, "echo reply"));
  391. }
  392. static int
  393. qnetd_client_msg_received_echo_request(struct qnetd_instance *instance, struct qnetd_client *client,
  394. const struct msg_decoded *msg, const struct dynar *msg_orig)
  395. {
  396. int res;
  397. struct send_buffer_list_entry *send_buffer;
  398. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  399. return (res == -1 ? -1 : 0);
  400. }
  401. if (!client->init_received) {
  402. qnetd_log(LOG_ERR, "Received echo request before init message. "
  403. "Sending error reply.");
  404. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  405. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  406. return (-1);
  407. }
  408. return (0);
  409. }
  410. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  411. if (send_buffer == NULL) {
  412. qnetd_log(LOG_ERR, "Can't alloc echo reply msg from list. "
  413. "Disconnecting client connection.");
  414. return (-1);
  415. }
  416. if (msg_create_echo_reply(&send_buffer->buffer, msg_orig) == -1) {
  417. qnetd_log(LOG_ERR, "Can't alloc echo reply msg. Disconnecting client connection.");
  418. return (-1);
  419. }
  420. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  421. return (0);
  422. }
  423. static int
  424. qnetd_client_msg_received_node_list(struct qnetd_instance *instance, struct qnetd_client *client,
  425. const struct msg_decoded *msg)
  426. {
  427. int res;
  428. struct send_buffer_list_entry *send_buffer;
  429. enum tlv_reply_error_code reply_error_code;
  430. enum tlv_vote result_vote;
  431. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  432. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  433. return (res == -1 ? -1 : 0);
  434. }
  435. if (!client->init_received) {
  436. qnetd_log(LOG_ERR, "Received node list message before init message. "
  437. "Sending error reply.");
  438. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  439. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  440. return (-1);
  441. }
  442. return (0);
  443. }
  444. if (!msg->node_list_type_set) {
  445. qnetd_log(LOG_ERR, "Received node list message without node list type set. "
  446. "Sending error reply.");
  447. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  448. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  449. return (-1);
  450. }
  451. return (0);
  452. }
  453. if (!msg->seq_number_set) {
  454. qnetd_log(LOG_ERR, "Received node list message without seq number set. "
  455. "Sending error reply.");
  456. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  457. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  458. return (-1);
  459. }
  460. return (0);
  461. }
  462. switch (msg->node_list_type) {
  463. case TLV_NODE_LIST_TYPE_INITIAL_CONFIG:
  464. case TLV_NODE_LIST_TYPE_CHANGED_CONFIG:
  465. reply_error_code = qnetd_algorithm_config_node_list_received(client,
  466. msg->seq_number, msg->config_version_set, msg->config_version,
  467. &msg->nodes,
  468. (msg->node_list_type == TLV_NODE_LIST_TYPE_INITIAL_CONFIG),
  469. &result_vote);
  470. break;
  471. case TLV_NODE_LIST_TYPE_MEMBERSHIP:
  472. if (!msg->ring_id_set) {
  473. qnetd_log(LOG_ERR, "Received node list message without ring id number set. "
  474. "Sending error reply.");
  475. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  476. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  477. return (-1);
  478. }
  479. return (0);
  480. }
  481. reply_error_code = qnetd_algorithm_membership_node_list_received(client,
  482. msg->seq_number, &msg->ring_id, &msg->nodes, &result_vote);
  483. break;
  484. case TLV_NODE_LIST_TYPE_QUORUM:
  485. if (!msg->quorate_set) {
  486. qnetd_log(LOG_ERR, "Received quorum list message without quorate set. "
  487. "Sending error reply.");
  488. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  489. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  490. return (-1);
  491. }
  492. return (0);
  493. }
  494. reply_error_code = qnetd_algorithm_quorum_node_list_received(client,
  495. msg->seq_number,msg->quorate, &msg->nodes, &result_vote);
  496. break;
  497. default:
  498. qnetd_log(LOG_ERR, "qnetd_client_msg_received_node_list fatal error. "
  499. "Unhandled node_list_type");
  500. exit(1);
  501. break;
  502. }
  503. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  504. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  505. "Sending error reply.");
  506. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  507. reply_error_code) != 0) {
  508. return (-1);
  509. }
  510. return (0);
  511. }
  512. /*
  513. * Store node list for future use
  514. */
  515. switch (msg->node_list_type) {
  516. case TLV_NODE_LIST_TYPE_INITIAL_CONFIG:
  517. case TLV_NODE_LIST_TYPE_CHANGED_CONFIG:
  518. node_list_free(&client->configuration_node_list);
  519. if (node_list_clone(&client->configuration_node_list, &msg->nodes) == -1) {
  520. qnetd_log(LOG_ERR, "Can't alloc config node list clone. "
  521. "Disconnecting client connection.");
  522. return (-1);
  523. }
  524. break;
  525. case TLV_NODE_LIST_TYPE_MEMBERSHIP:
  526. node_list_free(&client->last_membership_node_list);
  527. if (node_list_clone(&client->last_membership_node_list, &msg->nodes) == -1) {
  528. qnetd_log(LOG_ERR, "Can't alloc membership node list clone. "
  529. "Disconnecting client connection.");
  530. return (-1);
  531. }
  532. break;
  533. case TLV_NODE_LIST_TYPE_QUORUM:
  534. node_list_free(&client->last_quorum_node_list);
  535. if (node_list_clone(&client->last_quorum_node_list, &msg->nodes) == -1) {
  536. qnetd_log(LOG_ERR, "Can't alloc quorum node list clone. "
  537. "Disconnecting client connection.");
  538. return (-1);
  539. }
  540. break;
  541. default:
  542. qnetd_log(LOG_ERR, "qnetd_client_msg_received_node_list fatal error. "
  543. "Unhandled node_list_type");
  544. exit(1);
  545. break;
  546. }
  547. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  548. if (send_buffer == NULL) {
  549. qnetd_log(LOG_ERR, "Can't alloc node list reply msg from list. "
  550. "Disconnecting client connection.");
  551. return (-1);
  552. }
  553. if (msg_create_node_list_reply(&send_buffer->buffer, msg->seq_number, result_vote) == -1) {
  554. qnetd_log(LOG_ERR, "Can't alloc node list reply msg. "
  555. "Disconnecting client connection.");
  556. return (-1);
  557. }
  558. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  559. return (0);
  560. }
  561. static int
  562. qnetd_client_msg_received_node_list_reply(struct qnetd_instance *instance,
  563. struct qnetd_client *client, const struct msg_decoded *msg)
  564. {
  565. return (qnetd_client_msg_received_unexpected_msg(client, msg, "node list reply"));
  566. }
  567. static int
  568. qnetd_client_msg_received_ask_for_vote(struct qnetd_instance *instance, struct qnetd_client *client,
  569. const struct msg_decoded *msg)
  570. {
  571. int res;
  572. struct send_buffer_list_entry *send_buffer;
  573. enum tlv_reply_error_code reply_error_code;
  574. enum tlv_vote result_vote;
  575. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  576. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  577. return (res == -1 ? -1 : 0);
  578. }
  579. if (!client->init_received) {
  580. qnetd_log(LOG_ERR, "Received ask for vote message before init message. "
  581. "Sending error reply.");
  582. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  583. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  584. return (-1);
  585. }
  586. return (0);
  587. }
  588. if (!msg->seq_number_set) {
  589. qnetd_log(LOG_ERR, "Received ask for vote message without seq number set. "
  590. "Sending error reply.");
  591. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  592. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  593. return (-1);
  594. }
  595. return (0);
  596. }
  597. reply_error_code = qnetd_algorithm_ask_for_vote_received(client, msg->seq_number,
  598. &result_vote);
  599. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  600. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  601. "Sending error reply.");
  602. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  603. reply_error_code) != 0) {
  604. return (-1);
  605. }
  606. return (0);
  607. }
  608. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  609. if (send_buffer == NULL) {
  610. qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg from list. "
  611. "Disconnecting client connection.");
  612. return (-1);
  613. }
  614. if (msg_create_ask_for_vote_reply(&send_buffer->buffer, msg->seq_number,
  615. result_vote) == -1) {
  616. qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg. "
  617. "Disconnecting client connection.");
  618. return (-1);
  619. }
  620. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  621. return (0);
  622. }
  623. static int
  624. qnetd_client_msg_received_ask_for_vote_reply(struct qnetd_instance *instance,
  625. struct qnetd_client *client, const struct msg_decoded *msg)
  626. {
  627. return (qnetd_client_msg_received_unexpected_msg(client, msg, "ask for vote reply"));
  628. }
  629. static int
  630. qnetd_client_msg_received_vote_info(struct qnetd_instance *instance, struct qnetd_client *client,
  631. const struct msg_decoded *msg)
  632. {
  633. return (qnetd_client_msg_received_unexpected_msg(client, msg, "vote info"));
  634. }
  635. static int
  636. qnetd_client_msg_received_vote_info_reply(struct qnetd_instance *instance,
  637. struct qnetd_client *client, const struct msg_decoded *msg)
  638. {
  639. int res;
  640. enum tlv_reply_error_code reply_error_code;
  641. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  642. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  643. return (res == -1 ? -1 : 0);
  644. }
  645. if (!client->init_received) {
  646. qnetd_log(LOG_ERR, "Received vote info reply before init message. "
  647. "Sending error reply.");
  648. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  649. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  650. return (-1);
  651. }
  652. return (0);
  653. }
  654. if (!msg->seq_number_set) {
  655. qnetd_log(LOG_ERR, "Received vote info reply message without seq number set. "
  656. "Sending error reply.");
  657. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  658. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  659. return (-1);
  660. }
  661. return (0);
  662. }
  663. reply_error_code = qnetd_algorithm_vote_info_reply_received(client, msg->seq_number);
  664. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  665. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  666. "Sending error reply.");
  667. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  668. reply_error_code) != 0) {
  669. return (-1);
  670. }
  671. return (0);
  672. }
  673. return (0);
  674. }
  675. int
  676. qnetd_client_msg_received(struct qnetd_instance *instance, struct qnetd_client *client)
  677. {
  678. struct msg_decoded msg;
  679. int res;
  680. int ret_val;
  681. msg_decoded_init(&msg);
  682. res = msg_decode(&client->receive_buffer, &msg);
  683. if (res != 0) {
  684. /*
  685. * Error occurred. Send server error.
  686. */
  687. qnetd_log_msg_decode_error(res);
  688. qnetd_log(LOG_INFO, "Sending back error message");
  689. if (qnetd_client_send_err(client, msg.seq_number_set, msg.seq_number,
  690. TLV_REPLY_ERROR_CODE_ERROR_DECODING_MSG) != 0) {
  691. return (-1);
  692. }
  693. return (0);
  694. }
  695. ret_val = 0;
  696. switch (msg.type) {
  697. case MSG_TYPE_PREINIT:
  698. ret_val = qnetd_client_msg_received_preinit(instance, client, &msg);
  699. break;
  700. case MSG_TYPE_PREINIT_REPLY:
  701. ret_val = qnetd_client_msg_received_preinit_reply(instance, client, &msg);
  702. break;
  703. case MSG_TYPE_STARTTLS:
  704. ret_val = qnetd_client_msg_received_starttls(instance, client, &msg);
  705. break;
  706. case MSG_TYPE_INIT:
  707. ret_val = qnetd_client_msg_received_init(instance, client, &msg);
  708. break;
  709. case MSG_TYPE_INIT_REPLY:
  710. ret_val = qnetd_client_msg_received_init_reply(instance, client, &msg);
  711. break;
  712. case MSG_TYPE_SERVER_ERROR:
  713. ret_val = qnetd_client_msg_received_server_error(instance, client, &msg);
  714. break;
  715. case MSG_TYPE_SET_OPTION:
  716. ret_val = qnetd_client_msg_received_set_option(instance, client, &msg);
  717. break;
  718. case MSG_TYPE_SET_OPTION_REPLY:
  719. ret_val = qnetd_client_msg_received_set_option_reply(instance, client, &msg);
  720. break;
  721. case MSG_TYPE_ECHO_REQUEST:
  722. ret_val = qnetd_client_msg_received_echo_request(instance, client, &msg,
  723. &client->receive_buffer);
  724. break;
  725. case MSG_TYPE_ECHO_REPLY:
  726. ret_val = qnetd_client_msg_received_echo_reply(instance, client, &msg);
  727. break;
  728. case MSG_TYPE_NODE_LIST:
  729. ret_val = qnetd_client_msg_received_node_list(instance, client, &msg);
  730. break;
  731. case MSG_TYPE_NODE_LIST_REPLY:
  732. ret_val = qnetd_client_msg_received_node_list_reply(instance, client, &msg);
  733. break;
  734. case MSG_TYPE_ASK_FOR_VOTE:
  735. ret_val = qnetd_client_msg_received_ask_for_vote(instance, client, &msg);
  736. break;
  737. case MSG_TYPE_ASK_FOR_VOTE_REPLY:
  738. ret_val = qnetd_client_msg_received_ask_for_vote_reply(instance, client, &msg);
  739. break;
  740. case MSG_TYPE_VOTE_INFO:
  741. ret_val = qnetd_client_msg_received_vote_info(instance, client, &msg);
  742. break;
  743. case MSG_TYPE_VOTE_INFO_REPLY:
  744. ret_val = qnetd_client_msg_received_vote_info_reply(instance, client, &msg);
  745. break;
  746. default:
  747. qnetd_log(LOG_ERR, "Unsupported message %u received from client. "
  748. "Sending back error message", msg.type);
  749. if (qnetd_client_send_err(client, msg.seq_number_set, msg.seq_number,
  750. TLV_REPLY_ERROR_CODE_UNSUPPORTED_MESSAGE) != 0) {
  751. ret_val = -1;
  752. }
  753. break;
  754. }
  755. msg_decoded_destroy(&msg);
  756. return (ret_val);
  757. }