qnetd-client-msg-received.c 32 KB

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