qnetd-client-msg-received.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016
  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. static int
  198. qnetd_client_msg_received_init(struct qnetd_instance *instance, struct qnetd_client *client,
  199. const struct msg_decoded *msg)
  200. {
  201. int res;
  202. size_t zi;
  203. enum msg_type *supported_msgs;
  204. size_t no_supported_msgs;
  205. enum tlv_opt_type *supported_opts;
  206. size_t no_supported_opts;
  207. struct send_buffer_list_entry *send_buffer;
  208. enum tlv_reply_error_code reply_error_code;
  209. struct qnetd_cluster *cluster;
  210. supported_msgs = NULL;
  211. supported_opts = NULL;
  212. no_supported_msgs = 0;
  213. no_supported_opts = 0;
  214. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  215. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  216. return (res == -1 ? -1 : 0);
  217. }
  218. if (!client->preinit_received) {
  219. qnetd_log(LOG_ERR, "Received init before preinit message. Sending error reply.");
  220. reply_error_code = TLV_REPLY_ERROR_CODE_PREINIT_REQUIRED;
  221. }
  222. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->node_id_set) {
  223. qnetd_log(LOG_ERR, "Received init message without node id set. "
  224. "Sending error reply.");
  225. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  226. } else {
  227. client->node_id_set = 1;
  228. client->node_id = msg->node_id;
  229. }
  230. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->heartbeat_interval_set) {
  231. qnetd_log(LOG_ERR, "Received init message without heartbeat interval set. "
  232. "Sending error reply.");
  233. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  234. } else {
  235. if (msg->heartbeat_interval < QNETD_HEARTBEAT_INTERVAL_MIN ||
  236. msg->heartbeat_interval > QNETD_HEARTBEAT_INTERVAL_MAX) {
  237. qnetd_log(LOG_ERR, "Client requested invalid heartbeat interval %u. "
  238. "Sending error reply.", msg->heartbeat_interval);
  239. reply_error_code = TLV_REPLY_ERROR_CODE_INVALID_HEARTBEAT_INTERVAL;
  240. } else {
  241. client->heartbeat_interval = msg->heartbeat_interval;
  242. }
  243. }
  244. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->tie_breaker_set) {
  245. qnetd_log(LOG_ERR, "Received init message without tie-breaker set. "
  246. "Sending error reply.");
  247. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  248. } else {
  249. memcpy(&client->tie_breaker, &msg->tie_breaker, sizeof(msg->tie_breaker));
  250. }
  251. if (msg->supported_messages != NULL) {
  252. /*
  253. * Client sent supported messages. For now this is ignored but in the future
  254. * this may be used to ensure backward compatibility.
  255. */
  256. /*
  257. for (i = 0; i < msg->no_supported_messages; i++) {
  258. qnetd_log(LOG_DEBUG, "Client supports %u message",
  259. (int)msg->supported_messages[i]);
  260. }
  261. */
  262. /*
  263. * Sent back supported messages
  264. */
  265. msg_get_supported_messages(&supported_msgs, &no_supported_msgs);
  266. }
  267. if (msg->supported_options != NULL) {
  268. /*
  269. * Client sent supported options. For now this is ignored but in the future
  270. * this may be used to ensure backward compatibility.
  271. */
  272. /*
  273. for (i = 0; i < msg->no_supported_options; i++) {
  274. qnetd_log(LOG_DEBUG, "Client supports %u option",
  275. (int)msg->supported_messages[i]);
  276. }
  277. */
  278. /*
  279. * Send back supported options
  280. */
  281. tlv_get_supported_options(&supported_opts, &no_supported_opts);
  282. }
  283. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->decision_algorithm_set) {
  284. qnetd_log(LOG_ERR, "Received init message without decision algorithm. "
  285. "Sending error reply.");
  286. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  287. } else {
  288. /*
  289. * Check if decision algorithm requested by client is supported
  290. */
  291. res = 0;
  292. for (zi = 0; zi < QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE && !res; zi++) {
  293. if (qnetd_static_supported_decision_algorithms[zi] ==
  294. msg->decision_algorithm) {
  295. res = 1;
  296. }
  297. }
  298. if (!res) {
  299. qnetd_log(LOG_ERR, "Client requested unsupported decision algorithm %u. "
  300. "Sending error reply.", msg->decision_algorithm);
  301. reply_error_code = TLV_REPLY_ERROR_CODE_UNSUPPORTED_DECISION_ALGORITHM;
  302. }
  303. client->decision_algorithm = msg->decision_algorithm;
  304. }
  305. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  306. cluster = qnetd_cluster_list_add_client(&instance->clusters, client);
  307. if (cluster == NULL) {
  308. qnetd_log(LOG_ERR, "Can't add client to cluster list. "
  309. "Sending error reply.");
  310. reply_error_code = TLV_REPLY_ERROR_CODE_INTERNAL_ERROR;
  311. } else {
  312. client->cluster = cluster;
  313. client->cluster_list = &instance->clusters;
  314. }
  315. }
  316. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  317. qnetd_log_debug_new_client_connected(client);
  318. reply_error_code = qnetd_algorithm_client_init(client);
  319. }
  320. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  321. /*
  322. * Correct init received
  323. */
  324. client->init_received = 1;
  325. } else {
  326. qnetd_log(LOG_ERR, "Algorithm returned error code. Sending error reply.");
  327. }
  328. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  329. if (send_buffer == NULL) {
  330. qnetd_log(LOG_ERR, "Can't alloc init reply msg from list. "
  331. "Disconnecting client connection.");
  332. return (-1);
  333. }
  334. if (msg_create_init_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  335. reply_error_code,
  336. supported_msgs, no_supported_msgs, supported_opts, no_supported_opts,
  337. instance->max_client_receive_size, instance->max_client_send_size,
  338. qnetd_static_supported_decision_algorithms,
  339. QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE) == -1) {
  340. qnetd_log(LOG_ERR, "Can't alloc init reply msg. Disconnecting client connection.");
  341. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  342. return (-1);
  343. }
  344. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  345. return (0);
  346. }
  347. static int
  348. qnetd_client_msg_received_init_reply(struct qnetd_instance *instance, struct qnetd_client *client,
  349. const struct msg_decoded *msg)
  350. {
  351. return (qnetd_client_msg_received_unexpected_msg(client, msg, "init reply"));
  352. }
  353. static int
  354. qnetd_client_msg_received_set_option_reply(struct qnetd_instance *instance,
  355. struct qnetd_client *client, const struct msg_decoded *msg)
  356. {
  357. return (qnetd_client_msg_received_unexpected_msg(client, msg, "set option reply"));
  358. }
  359. static int
  360. qnetd_client_msg_received_set_option(struct qnetd_instance *instance, struct qnetd_client *client,
  361. const struct msg_decoded *msg)
  362. {
  363. int res;
  364. struct send_buffer_list_entry *send_buffer;
  365. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  366. return (res == -1 ? -1 : 0);
  367. }
  368. if (!client->init_received) {
  369. qnetd_log(LOG_ERR, "Received set option message before init message. "
  370. "Sending error reply.");
  371. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  372. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  373. return (-1);
  374. }
  375. return (0);
  376. }
  377. if (msg->heartbeat_interval_set) {
  378. /*
  379. * Check if heartbeat interval is valid
  380. */
  381. if (msg->heartbeat_interval < QNETD_HEARTBEAT_INTERVAL_MIN ||
  382. msg->heartbeat_interval > QNETD_HEARTBEAT_INTERVAL_MAX) {
  383. qnetd_log(LOG_ERR, "Client requested invalid heartbeat interval %u. "
  384. "Sending error reply.", msg->heartbeat_interval);
  385. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  386. TLV_REPLY_ERROR_CODE_INVALID_HEARTBEAT_INTERVAL) != 0) {
  387. return (-1);
  388. }
  389. return (0);
  390. }
  391. client->heartbeat_interval = msg->heartbeat_interval;
  392. }
  393. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  394. if (send_buffer == NULL) {
  395. qnetd_log(LOG_ERR, "Can't alloc set option reply msg from list. "
  396. "Disconnecting client connection.");
  397. return (-1);
  398. }
  399. if (msg_create_set_option_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  400. client->heartbeat_interval) == -1) {
  401. qnetd_log(LOG_ERR, "Can't alloc set option reply msg. "
  402. "Disconnecting client connection.");
  403. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  404. return (-1);
  405. }
  406. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  407. return (0);
  408. }
  409. static int
  410. qnetd_client_msg_received_echo_reply(struct qnetd_instance *instance, struct qnetd_client *client,
  411. const struct msg_decoded *msg)
  412. {
  413. return (qnetd_client_msg_received_unexpected_msg(client, msg, "echo reply"));
  414. }
  415. static int
  416. qnetd_client_msg_received_echo_request(struct qnetd_instance *instance, struct qnetd_client *client,
  417. const struct msg_decoded *msg, const struct dynar *msg_orig)
  418. {
  419. int res;
  420. struct send_buffer_list_entry *send_buffer;
  421. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  422. return (res == -1 ? -1 : 0);
  423. }
  424. if (!client->init_received) {
  425. qnetd_log(LOG_ERR, "Received echo request before init message. "
  426. "Sending error reply.");
  427. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  428. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  429. return (-1);
  430. }
  431. return (0);
  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 echo reply msg from list. "
  436. "Disconnecting client connection.");
  437. return (-1);
  438. }
  439. if (msg_create_echo_reply(&send_buffer->buffer, msg_orig) == -1) {
  440. qnetd_log(LOG_ERR, "Can't alloc echo reply msg. Disconnecting client connection.");
  441. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  442. return (-1);
  443. }
  444. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  445. return (0);
  446. }
  447. static int
  448. qnetd_client_msg_received_node_list(struct qnetd_instance *instance, struct qnetd_client *client,
  449. const struct msg_decoded *msg)
  450. {
  451. int res;
  452. struct send_buffer_list_entry *send_buffer;
  453. enum tlv_reply_error_code reply_error_code;
  454. enum tlv_vote result_vote;
  455. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  456. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  457. return (res == -1 ? -1 : 0);
  458. }
  459. if (!client->init_received) {
  460. qnetd_log(LOG_ERR, "Received node list message before init message. "
  461. "Sending error reply.");
  462. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  463. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  464. return (-1);
  465. }
  466. return (0);
  467. }
  468. if (!msg->node_list_type_set) {
  469. qnetd_log(LOG_ERR, "Received node list message without node list type set. "
  470. "Sending error reply.");
  471. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  472. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  473. return (-1);
  474. }
  475. return (0);
  476. }
  477. if (!msg->seq_number_set) {
  478. qnetd_log(LOG_ERR, "Received node list message without seq number set. "
  479. "Sending error reply.");
  480. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  481. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  482. return (-1);
  483. }
  484. return (0);
  485. }
  486. result_vote = TLV_VOTE_NO_CHANGE;
  487. switch (msg->node_list_type) {
  488. case TLV_NODE_LIST_TYPE_INITIAL_CONFIG:
  489. case TLV_NODE_LIST_TYPE_CHANGED_CONFIG:
  490. qnetd_log_debug_config_node_list_received(client, msg->seq_number,
  491. msg->config_version_set, msg->config_version, &msg->nodes,
  492. (msg->node_list_type == TLV_NODE_LIST_TYPE_INITIAL_CONFIG));
  493. reply_error_code = qnetd_algorithm_config_node_list_received(client,
  494. msg->seq_number, msg->config_version_set, msg->config_version,
  495. &msg->nodes,
  496. (msg->node_list_type == TLV_NODE_LIST_TYPE_INITIAL_CONFIG),
  497. &result_vote);
  498. break;
  499. case TLV_NODE_LIST_TYPE_MEMBERSHIP:
  500. if (!msg->ring_id_set) {
  501. qnetd_log(LOG_ERR, "Received node list message without ring id number set. "
  502. "Sending error reply.");
  503. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  504. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  505. return (-1);
  506. }
  507. return (0);
  508. }
  509. qnetd_log_debug_membership_node_list_received(client, msg->seq_number, &msg->ring_id,
  510. &msg->nodes);
  511. reply_error_code = qnetd_algorithm_membership_node_list_received(client,
  512. msg->seq_number, &msg->ring_id, &msg->nodes, &result_vote);
  513. break;
  514. case TLV_NODE_LIST_TYPE_QUORUM:
  515. if (!msg->quorate_set) {
  516. qnetd_log(LOG_ERR, "Received quorum list message without quorate set. "
  517. "Sending error reply.");
  518. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  519. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  520. return (-1);
  521. }
  522. return (0);
  523. }
  524. qnetd_log_debug_quorum_node_list_received(client, msg->seq_number,msg->quorate,
  525. &msg->nodes);
  526. reply_error_code = qnetd_algorithm_quorum_node_list_received(client,
  527. msg->seq_number,msg->quorate, &msg->nodes, &result_vote);
  528. break;
  529. default:
  530. qnetd_log(LOG_ERR, "qnetd_client_msg_received_node_list fatal error. "
  531. "Unhandled node_list_type");
  532. exit(1);
  533. break;
  534. }
  535. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  536. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  537. "Sending error reply.");
  538. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  539. reply_error_code) != 0) {
  540. return (-1);
  541. }
  542. return (0);
  543. } else {
  544. qnetd_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(result_vote));
  545. }
  546. if (msg->node_list_type == TLV_NODE_LIST_TYPE_MEMBERSHIP &&
  547. result_vote == TLV_VOTE_NO_CHANGE) {
  548. qnetd_log(LOG_ERR, "qnetd_client_msg_received_node_list fatal error. "
  549. "node_list_type is membership and algorithm result vote is no_change");
  550. exit(1);
  551. }
  552. /*
  553. * Store node list for future use
  554. */
  555. switch (msg->node_list_type) {
  556. case TLV_NODE_LIST_TYPE_INITIAL_CONFIG:
  557. case TLV_NODE_LIST_TYPE_CHANGED_CONFIG:
  558. node_list_free(&client->configuration_node_list);
  559. if (node_list_clone(&client->configuration_node_list, &msg->nodes) == -1) {
  560. qnetd_log(LOG_ERR, "Can't alloc config node list clone. "
  561. "Disconnecting client connection.");
  562. return (-1);
  563. }
  564. break;
  565. case TLV_NODE_LIST_TYPE_MEMBERSHIP:
  566. node_list_free(&client->last_membership_node_list);
  567. if (node_list_clone(&client->last_membership_node_list, &msg->nodes) == -1) {
  568. qnetd_log(LOG_ERR, "Can't alloc membership node list clone. "
  569. "Disconnecting client connection.");
  570. return (-1);
  571. }
  572. memcpy(&client->last_ring_id, &msg->ring_id, sizeof(struct tlv_ring_id));
  573. break;
  574. case TLV_NODE_LIST_TYPE_QUORUM:
  575. node_list_free(&client->last_quorum_node_list);
  576. if (node_list_clone(&client->last_quorum_node_list, &msg->nodes) == -1) {
  577. qnetd_log(LOG_ERR, "Can't alloc quorum node list clone. "
  578. "Disconnecting client connection.");
  579. return (-1);
  580. }
  581. break;
  582. default:
  583. qnetd_log(LOG_ERR, "qnetd_client_msg_received_node_list fatal error. "
  584. "Unhandled node_list_type");
  585. exit(1);
  586. break;
  587. }
  588. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  589. if (send_buffer == NULL) {
  590. qnetd_log(LOG_ERR, "Can't alloc node list reply msg from list. "
  591. "Disconnecting client connection.");
  592. return (-1);
  593. }
  594. if (msg_create_node_list_reply(&send_buffer->buffer, msg->seq_number, msg->node_list_type,
  595. msg->ring_id_set, &msg->ring_id, result_vote) == -1) {
  596. qnetd_log(LOG_ERR, "Can't alloc node list reply msg. "
  597. "Disconnecting client connection.");
  598. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  599. return (-1);
  600. }
  601. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  602. return (0);
  603. }
  604. static int
  605. qnetd_client_msg_received_node_list_reply(struct qnetd_instance *instance,
  606. struct qnetd_client *client, const struct msg_decoded *msg)
  607. {
  608. return (qnetd_client_msg_received_unexpected_msg(client, msg, "node list reply"));
  609. }
  610. static int
  611. qnetd_client_msg_received_ask_for_vote(struct qnetd_instance *instance, struct qnetd_client *client,
  612. const struct msg_decoded *msg)
  613. {
  614. int res;
  615. struct send_buffer_list_entry *send_buffer;
  616. enum tlv_reply_error_code reply_error_code;
  617. enum tlv_vote result_vote;
  618. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  619. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  620. return (res == -1 ? -1 : 0);
  621. }
  622. if (!client->init_received) {
  623. qnetd_log(LOG_ERR, "Received ask for vote message before init message. "
  624. "Sending error reply.");
  625. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  626. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  627. return (-1);
  628. }
  629. return (0);
  630. }
  631. if (!msg->seq_number_set) {
  632. qnetd_log(LOG_ERR, "Received ask for vote message without seq number set. "
  633. "Sending error reply.");
  634. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  635. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  636. return (-1);
  637. }
  638. return (0);
  639. }
  640. qnetd_log_debug_ask_for_vote_received(client, msg->seq_number);
  641. reply_error_code = qnetd_algorithm_ask_for_vote_received(client, msg->seq_number,
  642. &result_vote);
  643. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  644. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  645. "Sending error reply.");
  646. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  647. reply_error_code) != 0) {
  648. return (-1);
  649. }
  650. return (0);
  651. } else {
  652. qnetd_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(result_vote));
  653. }
  654. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  655. if (send_buffer == NULL) {
  656. qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg from list. "
  657. "Disconnecting client connection.");
  658. return (-1);
  659. }
  660. if (msg_create_ask_for_vote_reply(&send_buffer->buffer, msg->seq_number,
  661. result_vote) == -1) {
  662. qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg. "
  663. "Disconnecting client connection.");
  664. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  665. return (-1);
  666. }
  667. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  668. return (0);
  669. }
  670. static int
  671. qnetd_client_msg_received_ask_for_vote_reply(struct qnetd_instance *instance,
  672. struct qnetd_client *client, const struct msg_decoded *msg)
  673. {
  674. return (qnetd_client_msg_received_unexpected_msg(client, msg, "ask for vote reply"));
  675. }
  676. static int
  677. qnetd_client_msg_received_vote_info(struct qnetd_instance *instance, struct qnetd_client *client,
  678. const struct msg_decoded *msg)
  679. {
  680. return (qnetd_client_msg_received_unexpected_msg(client, msg, "vote info"));
  681. }
  682. static int
  683. qnetd_client_msg_received_vote_info_reply(struct qnetd_instance *instance,
  684. struct qnetd_client *client, const struct msg_decoded *msg)
  685. {
  686. int res;
  687. enum tlv_reply_error_code reply_error_code;
  688. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  689. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  690. return (res == -1 ? -1 : 0);
  691. }
  692. if (!client->init_received) {
  693. qnetd_log(LOG_ERR, "Received vote info reply before init message. "
  694. "Sending error reply.");
  695. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  696. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  697. return (-1);
  698. }
  699. return (0);
  700. }
  701. if (!msg->seq_number_set) {
  702. qnetd_log(LOG_ERR, "Received vote info reply message without seq number set. "
  703. "Sending error reply.");
  704. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  705. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  706. return (-1);
  707. }
  708. return (0);
  709. }
  710. qnetd_log_debug_vote_info_reply_received(client, msg->seq_number);
  711. reply_error_code = qnetd_algorithm_vote_info_reply_received(client, msg->seq_number);
  712. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  713. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  714. "Sending error reply.");
  715. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  716. reply_error_code) != 0) {
  717. return (-1);
  718. }
  719. return (0);
  720. }
  721. return (0);
  722. }
  723. int
  724. qnetd_client_msg_received(struct qnetd_instance *instance, struct qnetd_client *client)
  725. {
  726. struct msg_decoded msg;
  727. int res;
  728. int ret_val;
  729. msg_decoded_init(&msg);
  730. res = msg_decode(&client->receive_buffer, &msg);
  731. if (res != 0) {
  732. /*
  733. * Error occurred. Send server error.
  734. */
  735. qnetd_log_msg_decode_error(res);
  736. qnetd_log(LOG_INFO, "Sending back error message");
  737. if (qnetd_client_send_err(client, msg.seq_number_set, msg.seq_number,
  738. TLV_REPLY_ERROR_CODE_ERROR_DECODING_MSG) != 0) {
  739. return (-1);
  740. }
  741. return (0);
  742. }
  743. ret_val = 0;
  744. switch (msg.type) {
  745. case MSG_TYPE_PREINIT:
  746. ret_val = qnetd_client_msg_received_preinit(instance, client, &msg);
  747. break;
  748. case MSG_TYPE_PREINIT_REPLY:
  749. ret_val = qnetd_client_msg_received_preinit_reply(instance, client, &msg);
  750. break;
  751. case MSG_TYPE_STARTTLS:
  752. ret_val = qnetd_client_msg_received_starttls(instance, client, &msg);
  753. break;
  754. case MSG_TYPE_INIT:
  755. ret_val = qnetd_client_msg_received_init(instance, client, &msg);
  756. break;
  757. case MSG_TYPE_INIT_REPLY:
  758. ret_val = qnetd_client_msg_received_init_reply(instance, client, &msg);
  759. break;
  760. case MSG_TYPE_SERVER_ERROR:
  761. ret_val = qnetd_client_msg_received_server_error(instance, client, &msg);
  762. break;
  763. case MSG_TYPE_SET_OPTION:
  764. ret_val = qnetd_client_msg_received_set_option(instance, client, &msg);
  765. break;
  766. case MSG_TYPE_SET_OPTION_REPLY:
  767. ret_val = qnetd_client_msg_received_set_option_reply(instance, client, &msg);
  768. break;
  769. case MSG_TYPE_ECHO_REQUEST:
  770. ret_val = qnetd_client_msg_received_echo_request(instance, client, &msg,
  771. &client->receive_buffer);
  772. break;
  773. case MSG_TYPE_ECHO_REPLY:
  774. ret_val = qnetd_client_msg_received_echo_reply(instance, client, &msg);
  775. break;
  776. case MSG_TYPE_NODE_LIST:
  777. ret_val = qnetd_client_msg_received_node_list(instance, client, &msg);
  778. break;
  779. case MSG_TYPE_NODE_LIST_REPLY:
  780. ret_val = qnetd_client_msg_received_node_list_reply(instance, client, &msg);
  781. break;
  782. case MSG_TYPE_ASK_FOR_VOTE:
  783. ret_val = qnetd_client_msg_received_ask_for_vote(instance, client, &msg);
  784. break;
  785. case MSG_TYPE_ASK_FOR_VOTE_REPLY:
  786. ret_val = qnetd_client_msg_received_ask_for_vote_reply(instance, client, &msg);
  787. break;
  788. case MSG_TYPE_VOTE_INFO:
  789. ret_val = qnetd_client_msg_received_vote_info(instance, client, &msg);
  790. break;
  791. case MSG_TYPE_VOTE_INFO_REPLY:
  792. ret_val = qnetd_client_msg_received_vote_info_reply(instance, client, &msg);
  793. break;
  794. default:
  795. qnetd_log(LOG_ERR, "Unsupported message %u received from client. "
  796. "Sending back error message", msg.type);
  797. if (qnetd_client_send_err(client, msg.seq_number_set, msg.seq_number,
  798. TLV_REPLY_ERROR_CODE_UNSUPPORTED_MESSAGE) != 0) {
  799. ret_val = -1;
  800. }
  801. break;
  802. }
  803. msg_decoded_destroy(&msg);
  804. return (ret_val);
  805. }