qnetd-client-msg-received.c 32 KB

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