qnetd-client-msg-received.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140
  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->heartbeat_interval_set) {
  276. qnetd_log(LOG_ERR, "Received init message without heartbeat interval set. "
  277. "Sending error reply.");
  278. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  279. } else {
  280. if (msg->heartbeat_interval < QNETD_HEARTBEAT_INTERVAL_MIN ||
  281. msg->heartbeat_interval > QNETD_HEARTBEAT_INTERVAL_MAX) {
  282. qnetd_log(LOG_ERR, "Client requested invalid heartbeat interval %u. "
  283. "Sending error reply.", msg->heartbeat_interval);
  284. reply_error_code = TLV_REPLY_ERROR_CODE_INVALID_HEARTBEAT_INTERVAL;
  285. } else {
  286. client->heartbeat_interval = msg->heartbeat_interval;
  287. }
  288. }
  289. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->tie_breaker_set) {
  290. qnetd_log(LOG_ERR, "Received init message without tie-breaker set. "
  291. "Sending error reply.");
  292. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  293. } else {
  294. memcpy(&client->tie_breaker, &msg->tie_breaker, sizeof(msg->tie_breaker));
  295. }
  296. if (msg->supported_messages != NULL) {
  297. /*
  298. * Client sent supported messages. For now this is ignored but in the future
  299. * this may be used to ensure backward compatibility.
  300. */
  301. /*
  302. for (i = 0; i < msg->no_supported_messages; i++) {
  303. qnetd_log(LOG_DEBUG, "Client supports %u message",
  304. (int)msg->supported_messages[i]);
  305. }
  306. */
  307. /*
  308. * Sent back supported messages
  309. */
  310. msg_get_supported_messages(&supported_msgs, &no_supported_msgs);
  311. }
  312. if (msg->supported_options != NULL) {
  313. /*
  314. * Client sent supported options. For now this is ignored but in the future
  315. * this may be used to ensure backward compatibility.
  316. */
  317. /*
  318. for (i = 0; i < msg->no_supported_options; i++) {
  319. qnetd_log(LOG_DEBUG, "Client supports %u option",
  320. (int)msg->supported_messages[i]);
  321. }
  322. */
  323. /*
  324. * Send back supported options
  325. */
  326. tlv_get_supported_options(&supported_opts, &no_supported_opts);
  327. }
  328. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->decision_algorithm_set) {
  329. qnetd_log(LOG_ERR, "Received init message without decision algorithm. "
  330. "Sending error reply.");
  331. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  332. } else {
  333. /*
  334. * Check if decision algorithm requested by client is supported
  335. */
  336. res = 0;
  337. for (zi = 0; zi < QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE && !res; zi++) {
  338. if (qnetd_static_supported_decision_algorithms[zi] ==
  339. msg->decision_algorithm) {
  340. res = 1;
  341. }
  342. }
  343. if (!res) {
  344. qnetd_log(LOG_ERR, "Client requested unsupported decision algorithm %u. "
  345. "Sending error reply.", msg->decision_algorithm);
  346. reply_error_code = TLV_REPLY_ERROR_CODE_UNSUPPORTED_DECISION_ALGORITHM;
  347. }
  348. client->decision_algorithm = msg->decision_algorithm;
  349. }
  350. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  351. reply_error_code = qnetd_client_msg_received_init_check_new_client(instance,
  352. client);
  353. }
  354. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  355. cluster = qnetd_cluster_list_add_client(&instance->clusters, client);
  356. if (cluster == NULL) {
  357. qnetd_log(LOG_ERR, "Can't add client to cluster list. "
  358. "Sending error reply.");
  359. reply_error_code = TLV_REPLY_ERROR_CODE_INTERNAL_ERROR;
  360. } else {
  361. client->cluster = cluster;
  362. client->cluster_list = &instance->clusters;
  363. }
  364. }
  365. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  366. qnetd_log_debug_new_client_connected(client);
  367. reply_error_code = qnetd_algorithm_client_init(client);
  368. }
  369. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  370. /*
  371. * Correct init received
  372. */
  373. client->init_received = 1;
  374. } else {
  375. qnetd_log(LOG_ERR, "Algorithm returned error code. Sending error reply.");
  376. }
  377. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  378. if (send_buffer == NULL) {
  379. qnetd_log(LOG_ERR, "Can't alloc init reply msg from list. "
  380. "Disconnecting client connection.");
  381. return (-1);
  382. }
  383. if (msg_create_init_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  384. reply_error_code,
  385. supported_msgs, no_supported_msgs, supported_opts, no_supported_opts,
  386. instance->max_client_receive_size, instance->max_client_send_size,
  387. qnetd_static_supported_decision_algorithms,
  388. QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE) == -1) {
  389. qnetd_log(LOG_ERR, "Can't alloc init reply msg. Disconnecting client connection.");
  390. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  391. return (-1);
  392. }
  393. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  394. return (0);
  395. }
  396. static int
  397. qnetd_client_msg_received_init_reply(struct qnetd_instance *instance, struct qnetd_client *client,
  398. const struct msg_decoded *msg)
  399. {
  400. return (qnetd_client_msg_received_unexpected_msg(client, msg, "init reply"));
  401. }
  402. static int
  403. qnetd_client_msg_received_set_option_reply(struct qnetd_instance *instance,
  404. struct qnetd_client *client, const struct msg_decoded *msg)
  405. {
  406. return (qnetd_client_msg_received_unexpected_msg(client, msg, "set option reply"));
  407. }
  408. static int
  409. qnetd_client_msg_received_set_option(struct qnetd_instance *instance, struct qnetd_client *client,
  410. const struct msg_decoded *msg)
  411. {
  412. int res;
  413. struct send_buffer_list_entry *send_buffer;
  414. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  415. return (res == -1 ? -1 : 0);
  416. }
  417. if (!client->init_received) {
  418. qnetd_log(LOG_ERR, "Received set option message before init message. "
  419. "Sending error reply.");
  420. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  421. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  422. return (-1);
  423. }
  424. return (0);
  425. }
  426. if (msg->heartbeat_interval_set) {
  427. /*
  428. * Check if heartbeat interval is valid
  429. */
  430. if (msg->heartbeat_interval < QNETD_HEARTBEAT_INTERVAL_MIN ||
  431. msg->heartbeat_interval > QNETD_HEARTBEAT_INTERVAL_MAX) {
  432. qnetd_log(LOG_ERR, "Client requested invalid heartbeat interval %u. "
  433. "Sending error reply.", msg->heartbeat_interval);
  434. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  435. TLV_REPLY_ERROR_CODE_INVALID_HEARTBEAT_INTERVAL) != 0) {
  436. return (-1);
  437. }
  438. return (0);
  439. }
  440. client->heartbeat_interval = msg->heartbeat_interval;
  441. }
  442. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  443. if (send_buffer == NULL) {
  444. qnetd_log(LOG_ERR, "Can't alloc set option reply msg from list. "
  445. "Disconnecting client connection.");
  446. return (-1);
  447. }
  448. if (msg_create_set_option_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  449. client->heartbeat_interval) == -1) {
  450. qnetd_log(LOG_ERR, "Can't alloc set option reply msg. "
  451. "Disconnecting client connection.");
  452. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  453. return (-1);
  454. }
  455. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  456. return (0);
  457. }
  458. static int
  459. qnetd_client_msg_received_echo_reply(struct qnetd_instance *instance, struct qnetd_client *client,
  460. const struct msg_decoded *msg)
  461. {
  462. return (qnetd_client_msg_received_unexpected_msg(client, msg, "echo reply"));
  463. }
  464. static int
  465. qnetd_client_msg_received_echo_request(struct qnetd_instance *instance, struct qnetd_client *client,
  466. const struct msg_decoded *msg, const struct dynar *msg_orig)
  467. {
  468. int res;
  469. struct send_buffer_list_entry *send_buffer;
  470. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  471. return (res == -1 ? -1 : 0);
  472. }
  473. if (!client->init_received) {
  474. qnetd_log(LOG_ERR, "Received echo request before init message. "
  475. "Sending error reply.");
  476. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  477. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  478. return (-1);
  479. }
  480. return (0);
  481. }
  482. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  483. if (send_buffer == NULL) {
  484. qnetd_log(LOG_ERR, "Can't alloc echo reply msg from list. "
  485. "Disconnecting client connection.");
  486. return (-1);
  487. }
  488. if (msg_create_echo_reply(&send_buffer->buffer, msg_orig) == -1) {
  489. qnetd_log(LOG_ERR, "Can't alloc echo reply msg. Disconnecting client connection.");
  490. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  491. return (-1);
  492. }
  493. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  494. return (0);
  495. }
  496. static int
  497. qnetd_client_msg_received_node_list(struct qnetd_instance *instance, struct qnetd_client *client,
  498. const struct msg_decoded *msg)
  499. {
  500. int res;
  501. struct send_buffer_list_entry *send_buffer;
  502. enum tlv_reply_error_code reply_error_code;
  503. enum tlv_vote result_vote;
  504. int case_processed;
  505. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  506. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  507. return (res == -1 ? -1 : 0);
  508. }
  509. if (!client->init_received) {
  510. qnetd_log(LOG_ERR, "Received node list message before init message. "
  511. "Sending error reply.");
  512. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  513. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  514. return (-1);
  515. }
  516. return (0);
  517. }
  518. if (!msg->node_list_type_set) {
  519. qnetd_log(LOG_ERR, "Received node list message without node list type set. "
  520. "Sending error reply.");
  521. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  522. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  523. return (-1);
  524. }
  525. return (0);
  526. }
  527. if (!msg->seq_number_set) {
  528. qnetd_log(LOG_ERR, "Received node list message without seq number set. "
  529. "Sending error reply.");
  530. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  531. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  532. return (-1);
  533. }
  534. return (0);
  535. }
  536. result_vote = TLV_VOTE_NO_CHANGE;
  537. case_processed = 0;
  538. switch (msg->node_list_type) {
  539. case TLV_NODE_LIST_TYPE_INITIAL_CONFIG:
  540. case TLV_NODE_LIST_TYPE_CHANGED_CONFIG:
  541. case_processed = 1;
  542. qnetd_log_debug_config_node_list_received(client, msg->seq_number,
  543. msg->config_version_set, msg->config_version, &msg->nodes,
  544. (msg->node_list_type == TLV_NODE_LIST_TYPE_INITIAL_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. case_processed = 1;
  553. if (!msg->ring_id_set) {
  554. qnetd_log(LOG_ERR, "Received node list message without ring id number set. "
  555. "Sending error reply.");
  556. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  557. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  558. return (-1);
  559. }
  560. return (0);
  561. }
  562. qnetd_log_debug_membership_node_list_received(client, msg->seq_number, &msg->ring_id,
  563. &msg->nodes);
  564. reply_error_code = qnetd_algorithm_membership_node_list_received(client,
  565. msg->seq_number, &msg->ring_id, &msg->nodes, &result_vote);
  566. break;
  567. case TLV_NODE_LIST_TYPE_QUORUM:
  568. case_processed = 1;
  569. if (!msg->quorate_set) {
  570. qnetd_log(LOG_ERR, "Received quorum list message without quorate set. "
  571. "Sending error reply.");
  572. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  573. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  574. return (-1);
  575. }
  576. return (0);
  577. }
  578. qnetd_log_debug_quorum_node_list_received(client, msg->seq_number,msg->quorate,
  579. &msg->nodes);
  580. reply_error_code = qnetd_algorithm_quorum_node_list_received(client,
  581. msg->seq_number,msg->quorate, &msg->nodes, &result_vote);
  582. break;
  583. /*
  584. * Default is not defined intentionally. Compiler shows warning when new
  585. * node list type is added
  586. */
  587. }
  588. if (!case_processed) {
  589. qnetd_log(LOG_ERR, "qnetd_client_msg_received_node_list fatal error. "
  590. "Unhandled node_list_type");
  591. exit(1);
  592. }
  593. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  594. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  595. "Sending error reply.");
  596. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  597. reply_error_code) != 0) {
  598. return (-1);
  599. }
  600. return (0);
  601. } else {
  602. qnetd_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(result_vote));
  603. }
  604. if (msg->node_list_type == TLV_NODE_LIST_TYPE_MEMBERSHIP &&
  605. result_vote == TLV_VOTE_NO_CHANGE) {
  606. qnetd_log(LOG_ERR, "qnetd_client_msg_received_node_list fatal error. "
  607. "node_list_type is membership and algorithm result vote is no_change");
  608. exit(1);
  609. }
  610. /*
  611. * Store node list for future use
  612. */
  613. case_processed = 0;
  614. switch (msg->node_list_type) {
  615. case TLV_NODE_LIST_TYPE_INITIAL_CONFIG:
  616. case TLV_NODE_LIST_TYPE_CHANGED_CONFIG:
  617. case_processed = 1;
  618. node_list_free(&client->configuration_node_list);
  619. if (node_list_clone(&client->configuration_node_list, &msg->nodes) == -1) {
  620. qnetd_log(LOG_ERR, "Can't alloc config node list clone. "
  621. "Disconnecting client connection.");
  622. return (-1);
  623. }
  624. client->config_version_set = msg->config_version_set;
  625. client->config_version = msg->config_version;
  626. break;
  627. case TLV_NODE_LIST_TYPE_MEMBERSHIP:
  628. case_processed = 1;
  629. node_list_free(&client->last_membership_node_list);
  630. if (node_list_clone(&client->last_membership_node_list, &msg->nodes) == -1) {
  631. qnetd_log(LOG_ERR, "Can't alloc membership node list clone. "
  632. "Disconnecting client connection.");
  633. return (-1);
  634. }
  635. memcpy(&client->last_ring_id, &msg->ring_id, sizeof(struct tlv_ring_id));
  636. break;
  637. case TLV_NODE_LIST_TYPE_QUORUM:
  638. case_processed = 1;
  639. node_list_free(&client->last_quorum_node_list);
  640. if (node_list_clone(&client->last_quorum_node_list, &msg->nodes) == -1) {
  641. qnetd_log(LOG_ERR, "Can't alloc quorum node list clone. "
  642. "Disconnecting client connection.");
  643. return (-1);
  644. }
  645. break;
  646. /*
  647. * Default is not defined intentionally. Compiler shows warning when new
  648. * node list type is added
  649. */
  650. }
  651. if (!case_processed) {
  652. qnetd_log(LOG_ERR, "qnetd_client_msg_received_node_list fatal error. "
  653. "Unhandled node_list_type");
  654. exit(1);
  655. }
  656. /*
  657. * Store result vote
  658. */
  659. client->last_sent_vote = result_vote;
  660. if (result_vote == TLV_VOTE_ACK || result_vote == TLV_VOTE_NACK) {
  661. client->last_sent_ack_nack_vote = result_vote;
  662. }
  663. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  664. if (send_buffer == NULL) {
  665. qnetd_log(LOG_ERR, "Can't alloc node list reply msg from list. "
  666. "Disconnecting client connection.");
  667. return (-1);
  668. }
  669. if (msg_create_node_list_reply(&send_buffer->buffer, msg->seq_number, msg->node_list_type,
  670. msg->ring_id_set, &msg->ring_id, result_vote) == -1) {
  671. qnetd_log(LOG_ERR, "Can't alloc node list reply msg. "
  672. "Disconnecting client connection.");
  673. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  674. return (-1);
  675. }
  676. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  677. return (0);
  678. }
  679. static int
  680. qnetd_client_msg_received_node_list_reply(struct qnetd_instance *instance,
  681. struct qnetd_client *client, const struct msg_decoded *msg)
  682. {
  683. return (qnetd_client_msg_received_unexpected_msg(client, msg, "node list reply"));
  684. }
  685. static int
  686. qnetd_client_msg_received_ask_for_vote(struct qnetd_instance *instance, struct qnetd_client *client,
  687. const struct msg_decoded *msg)
  688. {
  689. int res;
  690. struct send_buffer_list_entry *send_buffer;
  691. enum tlv_reply_error_code reply_error_code;
  692. enum tlv_vote result_vote;
  693. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  694. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  695. return (res == -1 ? -1 : 0);
  696. }
  697. if (!client->init_received) {
  698. qnetd_log(LOG_ERR, "Received ask for vote message before init message. "
  699. "Sending error reply.");
  700. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  701. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  702. return (-1);
  703. }
  704. return (0);
  705. }
  706. if (!msg->seq_number_set) {
  707. qnetd_log(LOG_ERR, "Received ask for vote message without seq number set. "
  708. "Sending error reply.");
  709. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  710. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  711. return (-1);
  712. }
  713. return (0);
  714. }
  715. /*
  716. * Store result vote
  717. */
  718. client->last_sent_vote = result_vote;
  719. if (result_vote == TLV_VOTE_ACK || result_vote == TLV_VOTE_NACK) {
  720. client->last_sent_ack_nack_vote = result_vote;
  721. }
  722. qnetd_log_debug_ask_for_vote_received(client, msg->seq_number);
  723. reply_error_code = qnetd_algorithm_ask_for_vote_received(client, msg->seq_number,
  724. &result_vote);
  725. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  726. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  727. "Sending error reply.");
  728. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  729. reply_error_code) != 0) {
  730. return (-1);
  731. }
  732. return (0);
  733. } else {
  734. qnetd_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(result_vote));
  735. }
  736. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  737. if (send_buffer == NULL) {
  738. qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg from list. "
  739. "Disconnecting client connection.");
  740. return (-1);
  741. }
  742. if (msg_create_ask_for_vote_reply(&send_buffer->buffer, msg->seq_number,
  743. result_vote) == -1) {
  744. qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg. "
  745. "Disconnecting client connection.");
  746. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  747. return (-1);
  748. }
  749. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  750. return (0);
  751. }
  752. static int
  753. qnetd_client_msg_received_ask_for_vote_reply(struct qnetd_instance *instance,
  754. struct qnetd_client *client, const struct msg_decoded *msg)
  755. {
  756. return (qnetd_client_msg_received_unexpected_msg(client, msg, "ask for vote reply"));
  757. }
  758. static int
  759. qnetd_client_msg_received_vote_info(struct qnetd_instance *instance, struct qnetd_client *client,
  760. const struct msg_decoded *msg)
  761. {
  762. return (qnetd_client_msg_received_unexpected_msg(client, msg, "vote info"));
  763. }
  764. static int
  765. qnetd_client_msg_received_vote_info_reply(struct qnetd_instance *instance,
  766. struct qnetd_client *client, const struct msg_decoded *msg)
  767. {
  768. int res;
  769. enum tlv_reply_error_code reply_error_code;
  770. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  771. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  772. return (res == -1 ? -1 : 0);
  773. }
  774. if (!client->init_received) {
  775. qnetd_log(LOG_ERR, "Received vote info reply before init message. "
  776. "Sending error reply.");
  777. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  778. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  779. return (-1);
  780. }
  781. return (0);
  782. }
  783. if (!msg->seq_number_set) {
  784. qnetd_log(LOG_ERR, "Received vote info reply message without seq number set. "
  785. "Sending error reply.");
  786. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  787. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  788. return (-1);
  789. }
  790. return (0);
  791. }
  792. qnetd_log_debug_vote_info_reply_received(client, msg->seq_number);
  793. reply_error_code = qnetd_algorithm_vote_info_reply_received(client, msg->seq_number);
  794. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  795. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  796. "Sending error reply.");
  797. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  798. reply_error_code) != 0) {
  799. return (-1);
  800. }
  801. return (0);
  802. }
  803. return (0);
  804. }
  805. int
  806. qnetd_client_msg_received(struct qnetd_instance *instance, struct qnetd_client *client)
  807. {
  808. struct msg_decoded msg;
  809. int res;
  810. int ret_val;
  811. int msg_processed;
  812. client->dpd_msg_received_since_last_check = 1;
  813. msg_decoded_init(&msg);
  814. res = msg_decode(&client->receive_buffer, &msg);
  815. if (res != 0) {
  816. /*
  817. * Error occurred. Send server error.
  818. */
  819. qnetd_log_msg_decode_error(res);
  820. qnetd_log(LOG_INFO, "Sending back error message");
  821. if (qnetd_client_send_err(client, msg.seq_number_set, msg.seq_number,
  822. TLV_REPLY_ERROR_CODE_ERROR_DECODING_MSG) != 0) {
  823. return (-1);
  824. }
  825. return (0);
  826. }
  827. ret_val = 0;
  828. msg_processed = 0;
  829. switch (msg.type) {
  830. case MSG_TYPE_PREINIT:
  831. msg_processed = 1;
  832. ret_val = qnetd_client_msg_received_preinit(instance, client, &msg);
  833. break;
  834. case MSG_TYPE_PREINIT_REPLY:
  835. msg_processed = 1;
  836. ret_val = qnetd_client_msg_received_preinit_reply(instance, client, &msg);
  837. break;
  838. case MSG_TYPE_STARTTLS:
  839. msg_processed = 1;
  840. ret_val = qnetd_client_msg_received_starttls(instance, client, &msg);
  841. break;
  842. case MSG_TYPE_INIT:
  843. msg_processed = 1;
  844. ret_val = qnetd_client_msg_received_init(instance, client, &msg);
  845. break;
  846. case MSG_TYPE_INIT_REPLY:
  847. msg_processed = 1;
  848. ret_val = qnetd_client_msg_received_init_reply(instance, client, &msg);
  849. break;
  850. case MSG_TYPE_SERVER_ERROR:
  851. msg_processed = 1;
  852. ret_val = qnetd_client_msg_received_server_error(instance, client, &msg);
  853. break;
  854. case MSG_TYPE_SET_OPTION:
  855. msg_processed = 1;
  856. ret_val = qnetd_client_msg_received_set_option(instance, client, &msg);
  857. break;
  858. case MSG_TYPE_SET_OPTION_REPLY:
  859. msg_processed = 1;
  860. ret_val = qnetd_client_msg_received_set_option_reply(instance, client, &msg);
  861. break;
  862. case MSG_TYPE_ECHO_REQUEST:
  863. msg_processed = 1;
  864. ret_val = qnetd_client_msg_received_echo_request(instance, client, &msg,
  865. &client->receive_buffer);
  866. break;
  867. case MSG_TYPE_ECHO_REPLY:
  868. msg_processed = 1;
  869. ret_val = qnetd_client_msg_received_echo_reply(instance, client, &msg);
  870. break;
  871. case MSG_TYPE_NODE_LIST:
  872. msg_processed = 1;
  873. ret_val = qnetd_client_msg_received_node_list(instance, client, &msg);
  874. break;
  875. case MSG_TYPE_NODE_LIST_REPLY:
  876. msg_processed = 1;
  877. ret_val = qnetd_client_msg_received_node_list_reply(instance, client, &msg);
  878. break;
  879. case MSG_TYPE_ASK_FOR_VOTE:
  880. msg_processed = 1;
  881. ret_val = qnetd_client_msg_received_ask_for_vote(instance, client, &msg);
  882. break;
  883. case MSG_TYPE_ASK_FOR_VOTE_REPLY:
  884. msg_processed = 1;
  885. ret_val = qnetd_client_msg_received_ask_for_vote_reply(instance, client, &msg);
  886. break;
  887. case MSG_TYPE_VOTE_INFO:
  888. msg_processed = 1;
  889. ret_val = qnetd_client_msg_received_vote_info(instance, client, &msg);
  890. break;
  891. case MSG_TYPE_VOTE_INFO_REPLY:
  892. msg_processed = 1;
  893. ret_val = qnetd_client_msg_received_vote_info_reply(instance, client, &msg);
  894. break;
  895. /*
  896. * Default is not defined intentionally. Compiler shows warning when new
  897. * msg type is added.
  898. */
  899. }
  900. if (!msg_processed) {
  901. qnetd_log(LOG_ERR, "Unsupported message %u received from client. "
  902. "Sending back error message", msg.type);
  903. if (qnetd_client_send_err(client, msg.seq_number_set, msg.seq_number,
  904. TLV_REPLY_ERROR_CODE_UNSUPPORTED_MESSAGE) != 0) {
  905. ret_val = -1;
  906. }
  907. }
  908. msg_decoded_destroy(&msg);
  909. return (ret_val);
  910. }