qnetd-client-msg-received.c 31 KB

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