4
0

qnetd-client-msg-received.c 36 KB

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