2 * Copyright (c) 2015-2019 Red Hat, Inc.
6 * Author: Jan Friesse (jfriesse@redhat.com)
8 * This software licensed under BSD license, the text of which follows:
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
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.
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.
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"
45 * -1 means end of connection (EOF) or some other unhandled error. 0 = success
48 qdevice_net_socket_read(struct qdevice_net_instance
*instance
)
52 int orig_skipping_msg
;
54 orig_skipping_msg
= instance
->skipping_msg
;
56 res
= msgio_read(instance
->socket
, &instance
->receive_buffer
,
57 &instance
->msg_already_received_bytes
, &instance
->skipping_msg
);
59 if (!orig_skipping_msg
&& instance
->skipping_msg
) {
60 log(LOG_DEBUG
, "msgio_read set skipping_msg");
72 log(LOG_DEBUG
, "Server closed connection");
73 instance
->disconnect_reason
= QDEVICE_NET_DISCONNECT_REASON_SERVER_CLOSED_CONNECTION
;
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
;
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
;
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
;
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
;
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
;
109 * Full message received / skipped
111 if (!instance
->skipping_msg
) {
112 if (qdevice_net_msg_received(instance
) == -1) {
116 log(LOG_CRIT
, "net_socket_read in skipping msg state");
120 instance
->skipping_msg
= 0;
121 instance
->msg_already_received_bytes
= 0;
122 dynar_clean(&instance
->receive_buffer
);
125 log(LOG_CRIT
, "qdevice_net_socket_read unhandled error %d", res
);
134 qdevice_net_socket_write_finished(struct qdevice_net_instance
*instance
)
136 PRFileDesc
*new_pr_fd
;
138 if (instance
->state
== QDEVICE_NET_INSTANCE_STATE_WAITING_STARTTLS_BEING_SENT
) {
140 * StartTLS sent to server. Begin with TLS handshake
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
;
155 if (qdevice_net_send_init(instance
) != 0) {
156 instance
->disconnect_reason
=
157 QDEVICE_NET_DISCONNECT_REASON_CANT_ALLOCATE_MSG_BUFFER
;
162 instance
->socket
= new_pr_fd
;
163 instance
->using_tls
= 1;
170 qdevice_net_socket_write(struct qdevice_net_instance
*instance
)
173 struct send_buffer_list_entry
*send_buffer
;
174 enum msg_type sent_msg_type
;
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
;
184 res
= msgio_write(instance
->socket
, &send_buffer
->buffer
,
185 &send_buffer
->msg_already_sent_bytes
);
188 sent_msg_type
= msg_get_type(&send_buffer
->buffer
);
190 send_buffer_list_delete(&instance
->send_buffer_list
, send_buffer
);
192 if (sent_msg_type
!= MSG_TYPE_ECHO_REQUEST
) {
193 if (qdevice_net_socket_write_finished(instance
) == -1) {
200 log_nss(LOG_CRIT
, "PR_Send returned 0");
201 instance
->disconnect_reason
= QDEVICE_NET_DISCONNECT_REASON_SERVER_CLOSED_CONNECTION
;
206 log_nss(LOG_ERR
, "Unhandled error when sending message to server");
207 instance
->disconnect_reason
= QDEVICE_NET_DISCONNECT_REASON_CANT_SEND_MESSAGE
;