qnetd-client-msg-received.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143
  1. /*
  2. * Copyright (c) 2015-2016 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-log-debug.h"
  39. #include "qnetd-client-send.h"
  40. #include "msg.h"
  41. #include "nss-sock.h"
  42. #include "qnetd-client-msg-received.h"
  43. /*
  44. * 0 - Success
  45. * -1 - Disconnect client
  46. * -2 - Error reply sent, but no need to disconnect client
  47. */
  48. static int
  49. qnetd_client_msg_received_check_tls(struct qnetd_instance *instance, struct qnetd_client *client,
  50. const struct msg_decoded *msg)
  51. {
  52. int check_certificate;
  53. int tls_required;
  54. CERTCertificate *peer_cert;
  55. int case_processed;
  56. check_certificate = 0;
  57. tls_required = 0;
  58. case_processed = 0;
  59. switch (instance->tls_supported) {
  60. case TLV_TLS_UNSUPPORTED:
  61. case_processed = 1;
  62. tls_required = 0;
  63. check_certificate = 0;
  64. break;
  65. case TLV_TLS_SUPPORTED:
  66. case_processed = 1;
  67. tls_required = 0;
  68. if (client->tls_started && instance->tls_client_cert_required &&
  69. !client->tls_peer_certificate_verified) {
  70. check_certificate = 1;
  71. }
  72. break;
  73. case TLV_TLS_REQUIRED:
  74. case_processed = 1;
  75. tls_required = 1;
  76. if (instance->tls_client_cert_required && !client->tls_peer_certificate_verified) {
  77. check_certificate = 1;
  78. }
  79. break;
  80. /*
  81. * Default is not defined intentionally. Compiler shows warning when new
  82. * tls supported is added
  83. */
  84. }
  85. if (!case_processed) {
  86. qnetd_log(LOG_ERR, "Unhandled instance tls supported %u", instance->tls_supported);
  87. exit(1);
  88. }
  89. if (tls_required && !client->tls_started) {
  90. qnetd_log(LOG_ERR, "TLS is required but doesn't started yet. "
  91. "Sending back error message");
  92. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  93. TLV_REPLY_ERROR_CODE_TLS_REQUIRED) != 0) {
  94. return (-1);
  95. }
  96. return (-2);
  97. }
  98. if (check_certificate) {
  99. peer_cert = SSL_PeerCertificate(client->socket);
  100. if (peer_cert == NULL) {
  101. qnetd_log(LOG_ERR, "Client doesn't sent valid certificate. "
  102. "Disconnecting client");
  103. return (-1);
  104. }
  105. if (CERT_VerifyCertName(peer_cert, client->cluster_name) != SECSuccess) {
  106. qnetd_log(LOG_ERR, "Client doesn't sent certificate with valid CN. "
  107. "Disconnecting client");
  108. CERT_DestroyCertificate(peer_cert);
  109. return (-1);
  110. }
  111. CERT_DestroyCertificate(peer_cert);
  112. client->tls_peer_certificate_verified = 1;
  113. }
  114. return (0);
  115. }
  116. static int
  117. qnetd_client_msg_received_preinit(struct qnetd_instance *instance, struct qnetd_client *client,
  118. const struct msg_decoded *msg)
  119. {
  120. struct send_buffer_list_entry *send_buffer;
  121. if (msg->cluster_name == NULL) {
  122. qnetd_log(LOG_ERR, "Received preinit message without cluster name. "
  123. "Sending error reply.");
  124. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  125. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  126. return (-1);
  127. }
  128. return (0);
  129. }
  130. client->cluster_name = malloc(msg->cluster_name_len + 1);
  131. if (client->cluster_name == NULL) {
  132. qnetd_log(LOG_ERR, "Can't allocate cluster name. Sending error reply.");
  133. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  134. TLV_REPLY_ERROR_CODE_INTERNAL_ERROR) != 0) {
  135. return (-1);
  136. }
  137. return (0);
  138. }
  139. memset(client->cluster_name, 0, msg->cluster_name_len + 1);
  140. memcpy(client->cluster_name, msg->cluster_name, msg->cluster_name_len);
  141. client->cluster_name_len = msg->cluster_name_len;
  142. client->preinit_received = 1;
  143. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  144. if (send_buffer == NULL) {
  145. qnetd_log(LOG_ERR, "Can't alloc preinit reply msg from list. "
  146. "Disconnecting client connection.");
  147. return (-1);
  148. }
  149. if (msg_create_preinit_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  150. instance->tls_supported, instance->tls_client_cert_required) == 0) {
  151. qnetd_log(LOG_ERR, "Can't alloc preinit reply msg. "
  152. "Disconnecting client connection.");
  153. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  154. return (-1);
  155. };
  156. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  157. return (0);
  158. }
  159. static int
  160. qnetd_client_msg_received_unexpected_msg(struct qnetd_client *client,
  161. const struct msg_decoded *msg, const char *msg_str)
  162. {
  163. qnetd_log(LOG_ERR, "Received %s message. Sending back error message", msg_str);
  164. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  165. TLV_REPLY_ERROR_CODE_UNEXPECTED_MESSAGE) != 0) {
  166. return (-1);
  167. }
  168. return (0);
  169. }
  170. static int
  171. qnetd_client_msg_received_preinit_reply(struct qnetd_instance *instance,
  172. struct qnetd_client *client, const struct msg_decoded *msg)
  173. {
  174. return (qnetd_client_msg_received_unexpected_msg(client, msg, "preinit reply"));
  175. }
  176. static int
  177. qnetd_client_msg_received_starttls(struct qnetd_instance *instance, struct qnetd_client *client,
  178. const struct msg_decoded *msg)
  179. {
  180. PRFileDesc *new_pr_fd;
  181. if (!client->preinit_received) {
  182. qnetd_log(LOG_ERR, "Received starttls before preinit message. "
  183. "Sending error reply.");
  184. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  185. TLV_REPLY_ERROR_CODE_PREINIT_REQUIRED) != 0) {
  186. return (-1);
  187. }
  188. return (0);
  189. }
  190. if ((new_pr_fd = nss_sock_start_ssl_as_server(client->socket, instance->server.cert,
  191. instance->server.private_key, instance->tls_client_cert_required, 0, NULL)) == NULL) {
  192. qnetd_log_nss(LOG_ERR, "Can't start TLS. Disconnecting client.");
  193. return (-1);
  194. }
  195. client->tls_started = 1;
  196. client->tls_peer_certificate_verified = 0;
  197. client->socket = new_pr_fd;
  198. return (0);
  199. }
  200. static int
  201. qnetd_client_msg_received_server_error(struct qnetd_instance *instance, struct qnetd_client *client,
  202. const struct msg_decoded *msg)
  203. {
  204. return (qnetd_client_msg_received_unexpected_msg(client, msg, "server error"));
  205. }
  206. /*
  207. * Checks if new client send information are valid. It means:
  208. * - in cluster is no duplicate node with same nodeid
  209. * - it has same tie_breaker as other nodes in cluster
  210. * - it has same algorithm as other nodes in cluster
  211. */
  212. static enum tlv_reply_error_code
  213. qnetd_client_msg_received_init_check_new_client(struct qnetd_instance *instance,
  214. struct qnetd_client *new_client)
  215. {
  216. struct qnetd_cluster *cluster;
  217. struct qnetd_client *client;
  218. cluster = qnetd_cluster_list_find_by_name(&instance->clusters, new_client->cluster_name,
  219. new_client->cluster_name_len);
  220. if (cluster == NULL) {
  221. return (TLV_REPLY_ERROR_CODE_NO_ERROR);
  222. }
  223. TAILQ_FOREACH(client, &cluster->client_list, cluster_entries) {
  224. if (!tlv_tie_breaker_eq(&new_client->tie_breaker, &client->tie_breaker)) {
  225. qnetd_log(LOG_ERR, "Received init message contains tie-breaker which "
  226. "differs from rest of cluster. Sending error reply");
  227. return (TLV_REPLY_ERROR_CODE_TIE_BREAKER_DIFFERS_FROM_OTHER_NODES);
  228. }
  229. if (new_client->decision_algorithm != client->decision_algorithm) {
  230. qnetd_log(LOG_ERR, "Received init message contains algorithm which "
  231. "differs from rest of cluster. Sending error reply");
  232. return (TLV_REPLY_ERROR_CODE_ALGORITHM_DIFFERS_FROM_OTHER_NODES);
  233. }
  234. if (new_client->node_id == client->node_id) {
  235. qnetd_log(LOG_ERR, "Received init message contains node id which is "
  236. "duplicate of other node in cluster. Sending error reply");
  237. return (TLV_REPLY_ERROR_CODE_DUPLICATE_NODE_ID);
  238. }
  239. }
  240. return (TLV_REPLY_ERROR_CODE_NO_ERROR);
  241. }
  242. static int
  243. qnetd_client_msg_received_init(struct qnetd_instance *instance, struct qnetd_client *client,
  244. const struct msg_decoded *msg)
  245. {
  246. int res;
  247. size_t zi;
  248. enum msg_type *supported_msgs;
  249. size_t no_supported_msgs;
  250. enum tlv_opt_type *supported_opts;
  251. size_t no_supported_opts;
  252. struct send_buffer_list_entry *send_buffer;
  253. enum tlv_reply_error_code reply_error_code;
  254. struct qnetd_cluster *cluster;
  255. supported_msgs = NULL;
  256. supported_opts = NULL;
  257. no_supported_msgs = 0;
  258. no_supported_opts = 0;
  259. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  260. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  261. return (res == -1 ? -1 : 0);
  262. }
  263. if (!client->preinit_received) {
  264. qnetd_log(LOG_ERR, "Received init before preinit message. Sending error reply.");
  265. reply_error_code = TLV_REPLY_ERROR_CODE_PREINIT_REQUIRED;
  266. }
  267. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->node_id_set) {
  268. qnetd_log(LOG_ERR, "Received init message without node id set. "
  269. "Sending error reply.");
  270. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  271. } else {
  272. client->node_id_set = 1;
  273. client->node_id = msg->node_id;
  274. }
  275. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->ring_id_set) {
  276. qnetd_log(LOG_ERR, "Received init message without ring id set. "
  277. "Sending error reply.");
  278. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  279. } else {
  280. memcpy(&client->last_ring_id, &msg->ring_id, sizeof(struct tlv_ring_id));
  281. }
  282. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->heartbeat_interval_set) {
  283. qnetd_log(LOG_ERR, "Received init message without heartbeat interval set. "
  284. "Sending error reply.");
  285. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  286. } else {
  287. if (msg->heartbeat_interval < instance->advanced_settings->heartbeat_interval_min ||
  288. msg->heartbeat_interval > instance->advanced_settings->heartbeat_interval_max) {
  289. qnetd_log(LOG_ERR, "Client requested invalid heartbeat interval %u. "
  290. "Sending error reply.", msg->heartbeat_interval);
  291. reply_error_code = TLV_REPLY_ERROR_CODE_INVALID_HEARTBEAT_INTERVAL;
  292. } else {
  293. client->heartbeat_interval = msg->heartbeat_interval;
  294. }
  295. }
  296. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->tie_breaker_set) {
  297. qnetd_log(LOG_ERR, "Received init message without tie-breaker set. "
  298. "Sending error reply.");
  299. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  300. } else {
  301. memcpy(&client->tie_breaker, &msg->tie_breaker, sizeof(msg->tie_breaker));
  302. }
  303. if (msg->supported_messages != NULL) {
  304. /*
  305. * Client sent supported messages. For now this is ignored but in the future
  306. * this may be used to ensure backward compatibility.
  307. */
  308. /*
  309. for (i = 0; i < msg->no_supported_messages; i++) {
  310. qnetd_log(LOG_DEBUG, "Client supports %u message",
  311. (int)msg->supported_messages[i]);
  312. }
  313. */
  314. /*
  315. * Sent back supported messages
  316. */
  317. msg_get_supported_messages(&supported_msgs, &no_supported_msgs);
  318. }
  319. if (msg->supported_options != NULL) {
  320. /*
  321. * Client sent supported options. For now this is ignored but in the future
  322. * this may be used to ensure backward compatibility.
  323. */
  324. /*
  325. for (i = 0; i < msg->no_supported_options; i++) {
  326. qnetd_log(LOG_DEBUG, "Client supports %u option",
  327. (int)msg->supported_messages[i]);
  328. }
  329. */
  330. /*
  331. * Send back supported options
  332. */
  333. tlv_get_supported_options(&supported_opts, &no_supported_opts);
  334. }
  335. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->decision_algorithm_set) {
  336. qnetd_log(LOG_ERR, "Received init message without decision algorithm. "
  337. "Sending error reply.");
  338. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  339. } else {
  340. /*
  341. * Check if decision algorithm requested by client is supported
  342. */
  343. res = 0;
  344. for (zi = 0; zi < QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE && !res; zi++) {
  345. if (qnetd_static_supported_decision_algorithms[zi] ==
  346. msg->decision_algorithm) {
  347. res = 1;
  348. }
  349. }
  350. if (!res) {
  351. qnetd_log(LOG_ERR, "Client requested unsupported decision algorithm %u. "
  352. "Sending error reply.", msg->decision_algorithm);
  353. reply_error_code = TLV_REPLY_ERROR_CODE_UNSUPPORTED_DECISION_ALGORITHM;
  354. }
  355. client->decision_algorithm = msg->decision_algorithm;
  356. }
  357. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  358. reply_error_code = qnetd_client_msg_received_init_check_new_client(instance,
  359. client);
  360. }
  361. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  362. cluster = qnetd_cluster_list_add_client(&instance->clusters, client);
  363. if (cluster == NULL) {
  364. qnetd_log(LOG_ERR, "Can't add client to cluster list. "
  365. "Sending error reply.");
  366. reply_error_code = TLV_REPLY_ERROR_CODE_INTERNAL_ERROR;
  367. } else {
  368. client->cluster = cluster;
  369. client->cluster_list = &instance->clusters;
  370. }
  371. }
  372. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  373. qnetd_log_debug_new_client_connected(client);
  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. } else {
  382. qnetd_log(LOG_ERR, "Algorithm returned error code. Sending error reply.");
  383. }
  384. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  385. if (send_buffer == NULL) {
  386. qnetd_log(LOG_ERR, "Can't alloc init reply msg from list. "
  387. "Disconnecting client connection.");
  388. return (-1);
  389. }
  390. if (msg_create_init_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  391. reply_error_code,
  392. supported_msgs, no_supported_msgs, supported_opts, no_supported_opts,
  393. instance->advanced_settings->max_client_receive_size,
  394. instance->advanced_settings->max_client_send_size,
  395. qnetd_static_supported_decision_algorithms,
  396. QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE) == -1) {
  397. qnetd_log(LOG_ERR, "Can't alloc init reply msg. Disconnecting client connection.");
  398. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  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_msg_received_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 < instance->advanced_settings->heartbeat_interval_min ||
  439. msg->heartbeat_interval > instance->advanced_settings->heartbeat_interval_max) {
  440. qnetd_log(LOG_ERR, "Client requested invalid heartbeat interval %u. "
  441. "Sending error reply.", msg->heartbeat_interval);
  442. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  443. TLV_REPLY_ERROR_CODE_INVALID_HEARTBEAT_INTERVAL) != 0) {
  444. return (-1);
  445. }
  446. return (0);
  447. }
  448. client->heartbeat_interval = msg->heartbeat_interval;
  449. }
  450. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  451. if (send_buffer == NULL) {
  452. qnetd_log(LOG_ERR, "Can't alloc set option reply msg from list. "
  453. "Disconnecting client connection.");
  454. return (-1);
  455. }
  456. if (msg_create_set_option_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  457. client->heartbeat_interval) == -1) {
  458. qnetd_log(LOG_ERR, "Can't alloc set option reply msg. "
  459. "Disconnecting client connection.");
  460. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  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_msg_received_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. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  499. return (-1);
  500. }
  501. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  502. return (0);
  503. }
  504. static int
  505. qnetd_client_msg_received_node_list(struct qnetd_instance *instance, struct qnetd_client *client,
  506. const struct msg_decoded *msg)
  507. {
  508. int res;
  509. struct send_buffer_list_entry *send_buffer;
  510. enum tlv_reply_error_code reply_error_code;
  511. enum tlv_vote result_vote;
  512. int case_processed;
  513. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  514. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  515. return (res == -1 ? -1 : 0);
  516. }
  517. if (!client->init_received) {
  518. qnetd_log(LOG_ERR, "Received node list message before init message. "
  519. "Sending error reply.");
  520. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  521. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  522. return (-1);
  523. }
  524. return (0);
  525. }
  526. if (!msg->node_list_type_set) {
  527. qnetd_log(LOG_ERR, "Received node list message without node list type set. "
  528. "Sending error reply.");
  529. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  530. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  531. return (-1);
  532. }
  533. return (0);
  534. }
  535. if (!msg->seq_number_set) {
  536. qnetd_log(LOG_ERR, "Received node list message without seq number set. "
  537. "Sending error reply.");
  538. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  539. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  540. return (-1);
  541. }
  542. return (0);
  543. }
  544. result_vote = TLV_VOTE_NO_CHANGE;
  545. case_processed = 0;
  546. switch (msg->node_list_type) {
  547. case TLV_NODE_LIST_TYPE_INITIAL_CONFIG:
  548. case TLV_NODE_LIST_TYPE_CHANGED_CONFIG:
  549. case_processed = 1;
  550. qnetd_log_debug_config_node_list_received(client, msg->seq_number,
  551. msg->config_version_set, msg->config_version, &msg->nodes,
  552. (msg->node_list_type == TLV_NODE_LIST_TYPE_INITIAL_CONFIG));
  553. reply_error_code = qnetd_algorithm_config_node_list_received(client,
  554. msg->seq_number, msg->config_version_set, msg->config_version,
  555. &msg->nodes,
  556. (msg->node_list_type == TLV_NODE_LIST_TYPE_INITIAL_CONFIG),
  557. &result_vote);
  558. break;
  559. case TLV_NODE_LIST_TYPE_MEMBERSHIP:
  560. case_processed = 1;
  561. if (!msg->ring_id_set) {
  562. qnetd_log(LOG_ERR, "Received node list message without ring id number 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. qnetd_log_debug_membership_node_list_received(client, msg->seq_number, &msg->ring_id,
  571. &msg->nodes);
  572. reply_error_code = qnetd_algorithm_membership_node_list_received(client,
  573. msg->seq_number, &msg->ring_id, &msg->nodes, &result_vote);
  574. break;
  575. case TLV_NODE_LIST_TYPE_QUORUM:
  576. case_processed = 1;
  577. if (!msg->quorate_set) {
  578. qnetd_log(LOG_ERR, "Received quorum list message without quorate set. "
  579. "Sending error reply.");
  580. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  581. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  582. return (-1);
  583. }
  584. return (0);
  585. }
  586. qnetd_log_debug_quorum_node_list_received(client, msg->seq_number,msg->quorate,
  587. &msg->nodes);
  588. reply_error_code = qnetd_algorithm_quorum_node_list_received(client,
  589. msg->seq_number,msg->quorate, &msg->nodes, &result_vote);
  590. break;
  591. /*
  592. * Default is not defined intentionally. Compiler shows warning when new
  593. * node list type is added
  594. */
  595. }
  596. if (!case_processed) {
  597. qnetd_log(LOG_ERR, "qnetd_client_msg_received_node_list fatal error. "
  598. "Unhandled node_list_type");
  599. exit(1);
  600. }
  601. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  602. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  603. "Sending error reply.");
  604. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  605. reply_error_code) != 0) {
  606. return (-1);
  607. }
  608. return (0);
  609. } else {
  610. qnetd_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(result_vote));
  611. }
  612. /*
  613. * Store node list for future use
  614. */
  615. case_processed = 0;
  616. switch (msg->node_list_type) {
  617. case TLV_NODE_LIST_TYPE_INITIAL_CONFIG:
  618. case TLV_NODE_LIST_TYPE_CHANGED_CONFIG:
  619. case_processed = 1;
  620. node_list_free(&client->configuration_node_list);
  621. if (node_list_clone(&client->configuration_node_list, &msg->nodes) == -1) {
  622. qnetd_log(LOG_ERR, "Can't alloc config node list clone. "
  623. "Disconnecting client connection.");
  624. return (-1);
  625. }
  626. client->config_version_set = msg->config_version_set;
  627. client->config_version = msg->config_version;
  628. break;
  629. case TLV_NODE_LIST_TYPE_MEMBERSHIP:
  630. case_processed = 1;
  631. node_list_free(&client->last_membership_node_list);
  632. if (node_list_clone(&client->last_membership_node_list, &msg->nodes) == -1) {
  633. qnetd_log(LOG_ERR, "Can't alloc membership node list clone. "
  634. "Disconnecting client connection.");
  635. return (-1);
  636. }
  637. memcpy(&client->last_ring_id, &msg->ring_id, sizeof(struct tlv_ring_id));
  638. break;
  639. case TLV_NODE_LIST_TYPE_QUORUM:
  640. case_processed = 1;
  641. node_list_free(&client->last_quorum_node_list);
  642. if (node_list_clone(&client->last_quorum_node_list, &msg->nodes) == -1) {
  643. qnetd_log(LOG_ERR, "Can't alloc quorum node list clone. "
  644. "Disconnecting client connection.");
  645. return (-1);
  646. }
  647. break;
  648. /*
  649. * Default is not defined intentionally. Compiler shows warning when new
  650. * node list type is added
  651. */
  652. }
  653. if (!case_processed) {
  654. qnetd_log(LOG_ERR, "qnetd_client_msg_received_node_list fatal error. "
  655. "Unhandled node_list_type");
  656. exit(1);
  657. }
  658. /*
  659. * Store result vote
  660. */
  661. client->last_sent_vote = result_vote;
  662. if (result_vote == TLV_VOTE_ACK || result_vote == TLV_VOTE_NACK) {
  663. client->last_sent_ack_nack_vote = result_vote;
  664. }
  665. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  666. if (send_buffer == NULL) {
  667. qnetd_log(LOG_ERR, "Can't alloc node list reply msg from list. "
  668. "Disconnecting client connection.");
  669. return (-1);
  670. }
  671. if (msg_create_node_list_reply(&send_buffer->buffer, msg->seq_number, msg->node_list_type,
  672. &client->last_ring_id, result_vote) == -1) {
  673. qnetd_log(LOG_ERR, "Can't alloc node list reply msg. "
  674. "Disconnecting client connection.");
  675. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  676. return (-1);
  677. }
  678. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  679. return (0);
  680. }
  681. static int
  682. qnetd_client_msg_received_node_list_reply(struct qnetd_instance *instance,
  683. struct qnetd_client *client, const struct msg_decoded *msg)
  684. {
  685. return (qnetd_client_msg_received_unexpected_msg(client, msg, "node list reply"));
  686. }
  687. static int
  688. qnetd_client_msg_received_ask_for_vote(struct qnetd_instance *instance, struct qnetd_client *client,
  689. const struct msg_decoded *msg)
  690. {
  691. int res;
  692. struct send_buffer_list_entry *send_buffer;
  693. enum tlv_reply_error_code reply_error_code;
  694. enum tlv_vote result_vote;
  695. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  696. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  697. return (res == -1 ? -1 : 0);
  698. }
  699. if (!client->init_received) {
  700. qnetd_log(LOG_ERR, "Received ask for vote message before init message. "
  701. "Sending error reply.");
  702. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  703. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  704. return (-1);
  705. }
  706. return (0);
  707. }
  708. if (!msg->seq_number_set) {
  709. qnetd_log(LOG_ERR, "Received ask for vote message without seq number set. "
  710. "Sending error reply.");
  711. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  712. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  713. return (-1);
  714. }
  715. return (0);
  716. }
  717. qnetd_log_debug_ask_for_vote_received(client, msg->seq_number);
  718. reply_error_code = qnetd_algorithm_ask_for_vote_received(client, msg->seq_number,
  719. &result_vote);
  720. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  721. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  722. "Sending error reply.");
  723. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  724. reply_error_code) != 0) {
  725. return (-1);
  726. }
  727. return (0);
  728. } else {
  729. qnetd_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(result_vote));
  730. }
  731. /*
  732. * Store result vote
  733. */
  734. client->last_sent_vote = result_vote;
  735. if (result_vote == TLV_VOTE_ACK || result_vote == TLV_VOTE_NACK) {
  736. client->last_sent_ack_nack_vote = result_vote;
  737. }
  738. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  739. if (send_buffer == NULL) {
  740. qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg from list. "
  741. "Disconnecting client connection.");
  742. return (-1);
  743. }
  744. if (msg_create_ask_for_vote_reply(&send_buffer->buffer, msg->seq_number,
  745. &client->last_ring_id, result_vote) == -1) {
  746. qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg. "
  747. "Disconnecting client connection.");
  748. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  749. return (-1);
  750. }
  751. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  752. return (0);
  753. }
  754. static int
  755. qnetd_client_msg_received_ask_for_vote_reply(struct qnetd_instance *instance,
  756. struct qnetd_client *client, const struct msg_decoded *msg)
  757. {
  758. return (qnetd_client_msg_received_unexpected_msg(client, msg, "ask for vote reply"));
  759. }
  760. static int
  761. qnetd_client_msg_received_vote_info(struct qnetd_instance *instance, struct qnetd_client *client,
  762. const struct msg_decoded *msg)
  763. {
  764. return (qnetd_client_msg_received_unexpected_msg(client, msg, "vote info"));
  765. }
  766. static int
  767. qnetd_client_msg_received_vote_info_reply(struct qnetd_instance *instance,
  768. struct qnetd_client *client, const struct msg_decoded *msg)
  769. {
  770. int res;
  771. enum tlv_reply_error_code reply_error_code;
  772. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  773. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  774. return (res == -1 ? -1 : 0);
  775. }
  776. if (!client->init_received) {
  777. qnetd_log(LOG_ERR, "Received vote info reply before init message. "
  778. "Sending error reply.");
  779. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  780. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  781. return (-1);
  782. }
  783. return (0);
  784. }
  785. if (!msg->seq_number_set) {
  786. qnetd_log(LOG_ERR, "Received vote info reply message without seq number set. "
  787. "Sending error reply.");
  788. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  789. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  790. return (-1);
  791. }
  792. return (0);
  793. }
  794. qnetd_log_debug_vote_info_reply_received(client, msg->seq_number);
  795. reply_error_code = qnetd_algorithm_vote_info_reply_received(client, msg->seq_number);
  796. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  797. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  798. "Sending error reply.");
  799. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  800. reply_error_code) != 0) {
  801. return (-1);
  802. }
  803. return (0);
  804. }
  805. return (0);
  806. }
  807. int
  808. qnetd_client_msg_received(struct qnetd_instance *instance, struct qnetd_client *client)
  809. {
  810. struct msg_decoded msg;
  811. int res;
  812. int ret_val;
  813. int msg_processed;
  814. client->dpd_msg_received_since_last_check = 1;
  815. msg_decoded_init(&msg);
  816. res = msg_decode(&client->receive_buffer, &msg);
  817. if (res != 0) {
  818. /*
  819. * Error occurred. Send server error.
  820. */
  821. qnetd_log_msg_decode_error(res);
  822. qnetd_log(LOG_INFO, "Sending back error message");
  823. if (qnetd_client_send_err(client, msg.seq_number_set, msg.seq_number,
  824. TLV_REPLY_ERROR_CODE_ERROR_DECODING_MSG) != 0) {
  825. return (-1);
  826. }
  827. return (0);
  828. }
  829. ret_val = 0;
  830. msg_processed = 0;
  831. switch (msg.type) {
  832. case MSG_TYPE_PREINIT:
  833. msg_processed = 1;
  834. ret_val = qnetd_client_msg_received_preinit(instance, client, &msg);
  835. break;
  836. case MSG_TYPE_PREINIT_REPLY:
  837. msg_processed = 1;
  838. ret_val = qnetd_client_msg_received_preinit_reply(instance, client, &msg);
  839. break;
  840. case MSG_TYPE_STARTTLS:
  841. msg_processed = 1;
  842. ret_val = qnetd_client_msg_received_starttls(instance, client, &msg);
  843. break;
  844. case MSG_TYPE_INIT:
  845. msg_processed = 1;
  846. ret_val = qnetd_client_msg_received_init(instance, client, &msg);
  847. break;
  848. case MSG_TYPE_INIT_REPLY:
  849. msg_processed = 1;
  850. ret_val = qnetd_client_msg_received_init_reply(instance, client, &msg);
  851. break;
  852. case MSG_TYPE_SERVER_ERROR:
  853. msg_processed = 1;
  854. ret_val = qnetd_client_msg_received_server_error(instance, client, &msg);
  855. break;
  856. case MSG_TYPE_SET_OPTION:
  857. msg_processed = 1;
  858. ret_val = qnetd_client_msg_received_set_option(instance, client, &msg);
  859. break;
  860. case MSG_TYPE_SET_OPTION_REPLY:
  861. msg_processed = 1;
  862. ret_val = qnetd_client_msg_received_set_option_reply(instance, client, &msg);
  863. break;
  864. case MSG_TYPE_ECHO_REQUEST:
  865. msg_processed = 1;
  866. ret_val = qnetd_client_msg_received_echo_request(instance, client, &msg,
  867. &client->receive_buffer);
  868. break;
  869. case MSG_TYPE_ECHO_REPLY:
  870. msg_processed = 1;
  871. ret_val = qnetd_client_msg_received_echo_reply(instance, client, &msg);
  872. break;
  873. case MSG_TYPE_NODE_LIST:
  874. msg_processed = 1;
  875. ret_val = qnetd_client_msg_received_node_list(instance, client, &msg);
  876. break;
  877. case MSG_TYPE_NODE_LIST_REPLY:
  878. msg_processed = 1;
  879. ret_val = qnetd_client_msg_received_node_list_reply(instance, client, &msg);
  880. break;
  881. case MSG_TYPE_ASK_FOR_VOTE:
  882. msg_processed = 1;
  883. ret_val = qnetd_client_msg_received_ask_for_vote(instance, client, &msg);
  884. break;
  885. case MSG_TYPE_ASK_FOR_VOTE_REPLY:
  886. msg_processed = 1;
  887. ret_val = qnetd_client_msg_received_ask_for_vote_reply(instance, client, &msg);
  888. break;
  889. case MSG_TYPE_VOTE_INFO:
  890. msg_processed = 1;
  891. ret_val = qnetd_client_msg_received_vote_info(instance, client, &msg);
  892. break;
  893. case MSG_TYPE_VOTE_INFO_REPLY:
  894. msg_processed = 1;
  895. ret_val = qnetd_client_msg_received_vote_info_reply(instance, client, &msg);
  896. break;
  897. /*
  898. * Default is not defined intentionally. Compiler shows warning when new
  899. * msg type is added.
  900. */
  901. }
  902. if (!msg_processed) {
  903. qnetd_log(LOG_ERR, "Unsupported message %u received from client. "
  904. "Sending back error message", msg.type);
  905. if (qnetd_client_send_err(client, msg.seq_number_set, msg.seq_number,
  906. TLV_REPLY_ERROR_CODE_UNSUPPORTED_MESSAGE) != 0) {
  907. ret_val = -1;
  908. }
  909. }
  910. msg_decoded_destroy(&msg);
  911. return (ret_val);
  912. }