]> git.proxmox.com Git - mirror_corosync-qdevice.git/blob - qdevices/qdevice-net-socket.c
qdevice: Import log instead of qdevice-log
[mirror_corosync-qdevice.git] / qdevices / qdevice-net-socket.c
1 /*
2 * Copyright (c) 2015-2019 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
35 #include "log.h"
36 #include "msg.h"
37 #include "msgio.h"
38 #include "qnet-config.h"
39 #include "qdevice-net-msg-received.h"
40 #include "qdevice-net-nss.h"
41 #include "qdevice-net-send.h"
42 #include "qdevice-net-socket.h"
43
44 /*
45 * -1 means end of connection (EOF) or some other unhandled error. 0 = success
46 */
47 int
48 qdevice_net_socket_read(struct qdevice_net_instance *instance)
49 {
50 int res;
51 int ret_val;
52 int orig_skipping_msg;
53
54 orig_skipping_msg = instance->skipping_msg;
55
56 res = msgio_read(instance->socket, &instance->receive_buffer,
57 &instance->msg_already_received_bytes, &instance->skipping_msg);
58
59 if (!orig_skipping_msg && instance->skipping_msg) {
60 log(LOG_DEBUG, "msgio_read set skipping_msg");
61 }
62
63 ret_val = 0;
64
65 switch (res) {
66 case 0:
67 /*
68 * Partial read
69 */
70 break;
71 case -1:
72 log(LOG_DEBUG, "Server closed connection");
73 instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_SERVER_CLOSED_CONNECTION;
74 ret_val = -1;
75 break;
76 case -2:
77 log(LOG_ERR, "Unhandled error when reading from server. "
78 "Disconnecting from server");
79 instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_READ_MESSAGE;
80 ret_val = -1;
81 break;
82 case -3:
83 log(LOG_ERR, "Can't store message header from server. "
84 "Disconnecting from server");
85 instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_READ_MESSAGE;
86 ret_val = -1;
87 break;
88 case -4:
89 log(LOG_ERR, "Can't store message from server. "
90 "Disconnecting from server");
91 instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_READ_MESSAGE;
92 ret_val = -1;
93 break;
94 case -5:
95 log(LOG_WARNING, "Server sent unsupported msg type %u. "
96 "Disconnecting from server", msg_get_type(&instance->receive_buffer));
97 instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_UNSUPPORTED_MSG;
98 ret_val = -1;
99 break;
100 case -6:
101 log(LOG_WARNING,
102 "Server wants to send too long message %u bytes. Disconnecting from server",
103 msg_get_len(&instance->receive_buffer));
104 instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_READ_MESSAGE;
105 ret_val = -1;
106 break;
107 case 1:
108 /*
109 * Full message received / skipped
110 */
111 if (!instance->skipping_msg) {
112 if (qdevice_net_msg_received(instance) == -1) {
113 ret_val = -1;
114 }
115 } else {
116 log(LOG_CRIT, "net_socket_read in skipping msg state");
117 exit(1);
118 }
119
120 instance->skipping_msg = 0;
121 instance->msg_already_received_bytes = 0;
122 dynar_clean(&instance->receive_buffer);
123 break;
124 default:
125 log(LOG_CRIT, "qdevice_net_socket_read unhandled error %d", res);
126 exit(1);
127 break;
128 }
129
130 return (ret_val);
131 }
132
133 static int
134 qdevice_net_socket_write_finished(struct qdevice_net_instance *instance)
135 {
136 PRFileDesc *new_pr_fd;
137
138 if (instance->state == QDEVICE_NET_INSTANCE_STATE_WAITING_STARTTLS_BEING_SENT) {
139 /*
140 * StartTLS sent to server. Begin with TLS handshake
141 */
142 if ((new_pr_fd = nss_sock_start_ssl_as_client(instance->socket,
143 instance->advanced_settings->net_nss_qnetd_cn,
144 qdevice_net_nss_bad_cert_hook,
145 qdevice_net_nss_get_client_auth_data,
146 instance, 0, NULL)) == NULL) {
147 log_nss(LOG_ERR, "Can't start TLS");
148 instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_START_TLS;
149 return (-1);
150 }
151
152 /*
153 * And send init msg
154 */
155 if (qdevice_net_send_init(instance) != 0) {
156 instance->disconnect_reason =
157 QDEVICE_NET_DISCONNECT_REASON_CANT_ALLOCATE_MSG_BUFFER;
158
159 return (-1);
160 }
161
162 instance->socket = new_pr_fd;
163 instance->using_tls = 1;
164 }
165
166 return (0);
167 }
168
169 int
170 qdevice_net_socket_write(struct qdevice_net_instance *instance)
171 {
172 int res;
173 struct send_buffer_list_entry *send_buffer;
174 enum msg_type sent_msg_type;
175
176 send_buffer = send_buffer_list_get_active(&instance->send_buffer_list);
177 if (send_buffer == NULL) {
178 log(LOG_CRIT, "send_buffer_list_get_active returned NULL");
179 instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_SEND_MESSAGE;
180
181 return (-1);
182 }
183
184 res = msgio_write(instance->socket, &send_buffer->buffer,
185 &send_buffer->msg_already_sent_bytes);
186
187 if (res == 1) {
188 sent_msg_type = msg_get_type(&send_buffer->buffer);
189
190 send_buffer_list_delete(&instance->send_buffer_list, send_buffer);
191
192 if (sent_msg_type != MSG_TYPE_ECHO_REQUEST) {
193 if (qdevice_net_socket_write_finished(instance) == -1) {
194 return (-1);
195 }
196 }
197 }
198
199 if (res == -1) {
200 log_nss(LOG_CRIT, "PR_Send returned 0");
201 instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_SERVER_CLOSED_CONNECTION;
202 return (-1);
203 }
204
205 if (res == -2) {
206 log_nss(LOG_ERR, "Unhandled error when sending message to server");
207 instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_SEND_MESSAGE;
208
209 return (-1);
210 }
211
212 return (0);
213 }