qnetd-client-msg-received.c 36 KB

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