1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * fs/hmdfs/comm/transport.c
4 *
5 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
6 */
7
8 #include "transport.h"
9
10 #include <linux/freezer.h>
11 #include <linux/highmem.h>
12 #include <linux/kthread.h>
13 #include <linux/module.h>
14 #include <linux/net.h>
15 #include <linux/tcp.h>
16 #include <linux/time.h>
17 #include <linux/file.h>
18 #include <linux/sched/mm.h>
19
20 #include "device_node.h"
21 #include "hmdfs_trace.h"
22 #include "socket_adapter.h"
23 #include "authority/authentication.h"
24
25 #ifdef CONFIG_HMDFS_FS_ENCRYPTION
26 #include <net/tls.h>
27 #include "crypto.h"
28 #endif
29
30 typedef void (*connect_recv_handler)(struct connection *, void *, void *,
31 __u32);
32
33 static connect_recv_handler connect_recv_callback[CONNECT_STAT_COUNT] = {
34 [CONNECT_STAT_WAIT_REQUEST] = connection_handshake_recv_handler,
35 [CONNECT_STAT_WAIT_RESPONSE] = connection_handshake_recv_handler,
36 [CONNECT_STAT_WORKING] = connection_working_recv_handler,
37 [CONNECT_STAT_STOP] = NULL,
38 [CONNECT_STAT_WAIT_ACK] = connection_handshake_recv_handler,
39 [CONNECT_STAT_NEGO_FAIL] = NULL,
40 };
41
recvmsg_nofs(struct socket * sock,struct msghdr * msg,struct kvec * vec,size_t num,size_t size,int flags)42 static int recvmsg_nofs(struct socket *sock, struct msghdr *msg,
43 struct kvec *vec, size_t num, size_t size, int flags)
44 {
45 unsigned int nofs_flags;
46 int ret;
47
48 /* enable NOFS for memory allocation */
49 nofs_flags = memalloc_nofs_save();
50 ret = kernel_recvmsg(sock, msg, vec, num, size, flags);
51 memalloc_nofs_restore(nofs_flags);
52
53 return ret;
54 }
55
sendmsg_nofs(struct socket * sock,struct msghdr * msg,struct kvec * vec,size_t num,size_t size)56 static int sendmsg_nofs(struct socket *sock, struct msghdr *msg,
57 struct kvec *vec, size_t num, size_t size)
58 {
59 unsigned int nofs_flags;
60 int ret;
61
62 /* enable NOFS for memory allocation */
63 nofs_flags = memalloc_nofs_save();
64 ret = kernel_sendmsg(sock, msg, vec, num, size);
65 memalloc_nofs_restore(nofs_flags);
66
67 return ret;
68 }
69
tcp_set_recvtimeo(struct socket * sock,int timeout)70 static int tcp_set_recvtimeo(struct socket *sock, int timeout)
71 {
72 long jiffies_left = timeout * msecs_to_jiffies(MSEC_PER_SEC);
73
74 tcp_sock_set_nodelay(sock->sk);
75 tcp_sock_set_user_timeout(sock->sk, jiffies_left);
76 return 0;
77 }
78
hmdfs_tcpi_rtt(struct hmdfs_peer * con)79 uint32_t hmdfs_tcpi_rtt(struct hmdfs_peer *con)
80 {
81 uint32_t rtt_us = 0;
82 struct connection *conn_impl = NULL;
83 struct tcp_handle *tcp = NULL;
84
85 conn_impl = get_conn_impl(con, CONNECT_TYPE_TCP);
86 if (!conn_impl)
87 return rtt_us;
88 tcp = (struct tcp_handle *)(conn_impl->connect_handle);
89 if (tcp->sock)
90 rtt_us = tcp_sk(tcp->sock->sk)->srtt_us >> 3;
91 connection_put(conn_impl);
92 return rtt_us;
93 }
94
tcp_read_head_from_socket(struct socket * sock,void * buf,unsigned int to_read)95 static int tcp_read_head_from_socket(struct socket *sock, void *buf,
96 unsigned int to_read)
97 {
98 int rc = 0;
99 struct msghdr hmdfs_msg;
100 struct kvec iov;
101
102 iov.iov_base = buf;
103 iov.iov_len = to_read;
104 memset(&hmdfs_msg, 0, sizeof(hmdfs_msg));
105 hmdfs_msg.msg_flags = MSG_WAITALL;
106 hmdfs_msg.msg_control = NULL;
107 hmdfs_msg.msg_controllen = 0;
108 rc = recvmsg_nofs(sock, &hmdfs_msg, &iov, 1, to_read,
109 hmdfs_msg.msg_flags);
110 if (rc == -EAGAIN || rc == -ETIMEDOUT || rc == -EINTR ||
111 rc == -EBADMSG) {
112 usleep_range(1000, 2000);
113 return -EAGAIN;
114 }
115 // error occurred
116 if (rc != to_read) {
117 hmdfs_err("tcp recv error %d", rc);
118 return -ESHUTDOWN;
119 }
120 return 0;
121 }
122
tcp_read_buffer_from_socket(struct socket * sock,void * buf,unsigned int to_read)123 static int tcp_read_buffer_from_socket(struct socket *sock, void *buf,
124 unsigned int to_read)
125 {
126 int read_cnt = 0;
127 int retry_time = 0;
128 int rc = 0;
129 struct msghdr hmdfs_msg;
130 struct kvec iov;
131
132 do {
133 iov.iov_base = (char *)buf + read_cnt;
134 iov.iov_len = to_read - read_cnt;
135 memset(&hmdfs_msg, 0, sizeof(hmdfs_msg));
136 hmdfs_msg.msg_flags = MSG_WAITALL;
137 hmdfs_msg.msg_control = NULL;
138 hmdfs_msg.msg_controllen = 0;
139 rc = recvmsg_nofs(sock, &hmdfs_msg, &iov, 1,
140 to_read - read_cnt, hmdfs_msg.msg_flags);
141 if (rc == -EBADMSG) {
142 usleep_range(1000, 2000);
143 continue;
144 }
145 if (rc == -EAGAIN || rc == -ETIMEDOUT || rc == -EINTR) {
146 retry_time++;
147 hmdfs_info("read again %d", rc);
148 usleep_range(1000, 2000);
149 continue;
150 }
151 // error occurred
152 if (rc <= 0) {
153 hmdfs_err("tcp recv error %d", rc);
154 return -ESHUTDOWN;
155 }
156 read_cnt += rc;
157 if (read_cnt != to_read)
158 hmdfs_info("read again %d/%d", read_cnt, to_read);
159 } while (read_cnt < to_read && retry_time < MAX_RECV_RETRY_TIMES);
160 if (read_cnt == to_read)
161 return 0;
162 return -ESHUTDOWN;
163 }
164
hmdfs_drop_readpage_buffer(struct socket * sock,struct hmdfs_head_cmd * recv)165 static int hmdfs_drop_readpage_buffer(struct socket *sock,
166 struct hmdfs_head_cmd *recv)
167 {
168 unsigned int len;
169 void *buf = NULL;
170 int err;
171
172 len = le32_to_cpu(recv->data_len) - sizeof(struct hmdfs_head_cmd);
173 if (len > HMDFS_PAGE_SIZE || !len) {
174 hmdfs_err("recv invalid readpage length %u", len);
175 return -EINVAL;
176 }
177
178 /* Abort the connection if no memory */
179 buf = kmalloc(len, GFP_KERNEL);
180 if (!buf)
181 return -ESHUTDOWN;
182
183 err = tcp_read_buffer_from_socket(sock, buf, len);
184 kfree(buf);
185
186 return err;
187 }
188
hmdfs_get_readpage_buffer(struct socket * sock,struct hmdfs_head_cmd * recv,struct page * page)189 static int hmdfs_get_readpage_buffer(struct socket *sock,
190 struct hmdfs_head_cmd *recv,
191 struct page *page)
192 {
193 char *page_buf = NULL;
194 unsigned int out_len;
195 int err;
196
197 out_len = le32_to_cpu(recv->data_len) - sizeof(struct hmdfs_head_cmd);
198 if (out_len > HMDFS_PAGE_SIZE || !out_len) {
199 hmdfs_err("recv invalid readpage length %u", out_len);
200 return -EINVAL;
201 }
202
203 page_buf = kmap(page);
204 err = tcp_read_buffer_from_socket(sock, page_buf, out_len);
205 if (err)
206 goto out_unmap;
207 if (out_len != HMDFS_PAGE_SIZE)
208 memset(page_buf + out_len, 0, HMDFS_PAGE_SIZE - out_len);
209
210 out_unmap:
211 kunmap(page);
212 return err;
213 }
214
tcp_recvpage_tls(struct connection * connect,struct hmdfs_head_cmd * recv)215 static int tcp_recvpage_tls(struct connection *connect,
216 struct hmdfs_head_cmd *recv)
217 {
218 int ret = 0;
219 struct tcp_handle *tcp = NULL;
220 struct hmdfs_peer *node = NULL;
221 struct page *page = NULL;
222 struct hmdfs_async_work *async_work = NULL;
223 int rd_err;
224
225 if (!connect) {
226 hmdfs_err("tcp connect == NULL");
227 return -ESHUTDOWN;
228 }
229 node = connect->node;
230 tcp = (struct tcp_handle *)(connect->connect_handle);
231
232 rd_err = le32_to_cpu(recv->ret_code);
233 if (rd_err)
234 hmdfs_warning("tcp: readpage from peer %llu ret err %d",
235 node->device_id, rd_err);
236
237 async_work = (struct hmdfs_async_work *)hmdfs_find_msg_head(node,
238 le32_to_cpu(recv->msg_id));
239 if (!async_work || !cancel_delayed_work(&async_work->d_work))
240 goto out;
241
242 page = async_work->page;
243 if (!page) {
244 hmdfs_err("page not found");
245 goto out;
246 }
247
248 if (!rd_err) {
249 ret = hmdfs_get_readpage_buffer(tcp->sock, recv, page);
250 if (ret)
251 rd_err = ret;
252 }
253 hmdfs_client_recv_readpage(recv, rd_err, async_work);
254 asw_put(async_work);
255 return ret;
256
257 out:
258 /* async_work will be released by recvpage in normal processure */
259 if (async_work)
260 asw_put(async_work);
261 hmdfs_err_ratelimited("timeout and droppage");
262 hmdfs_client_resp_statis(node->sbi, F_READPAGE, HMDFS_RESP_DELAY, 0, 0);
263 if (!rd_err)
264 ret = hmdfs_drop_readpage_buffer(tcp->sock, recv);
265 return ret;
266 }
267
aeadcipher_cb(struct crypto_async_request * req,int error)268 static void aeadcipher_cb(struct crypto_async_request *req, int error)
269 {
270 struct aeadcrypt_result *result = req->data;
271
272 if (error == -EINPROGRESS)
273 return;
274 result->err = error;
275 complete(&result->completion);
276 }
277
aeadcipher_en_de(struct aead_request * req,struct aeadcrypt_result result,int flag)278 static int aeadcipher_en_de(struct aead_request *req,
279 struct aeadcrypt_result result, int flag)
280 {
281 int rc = 0;
282
283 if (flag)
284 rc = crypto_aead_encrypt(req);
285 else
286 rc = crypto_aead_decrypt(req);
287 switch (rc) {
288 case 0:
289 break;
290 case -EINPROGRESS:
291 case -EBUSY:
292 rc = wait_for_completion_interruptible(&result.completion);
293 if (!rc && !result.err)
294 reinit_completion(&result.completion);
295 break;
296 default:
297 hmdfs_err("returned rc %d result %d", rc, result.err);
298 break;
299 }
300 return rc;
301 }
302
set_aeadcipher(struct crypto_aead * tfm,struct aead_request * req,struct aeadcrypt_result * result)303 static int set_aeadcipher(struct crypto_aead *tfm, struct aead_request *req,
304 struct aeadcrypt_result *result)
305 {
306 init_completion(&result->completion);
307 aead_request_set_callback(
308 req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
309 aeadcipher_cb, result);
310 return 0;
311 }
312
aeadcipher_encrypt_buffer(struct connection * con,__u8 * src_buf,size_t src_len,__u8 * dst_buf,size_t dst_len)313 int aeadcipher_encrypt_buffer(struct connection *con, __u8 *src_buf,
314 size_t src_len, __u8 *dst_buf, size_t dst_len)
315 {
316 int ret = 0;
317 struct scatterlist src, dst;
318 struct aead_request *req = NULL;
319 struct aeadcrypt_result result;
320 __u8 cipher_iv[HMDFS_IV_SIZE];
321
322 if (src_len <= 0)
323 return -EINVAL;
324 if (!virt_addr_valid(src_buf) || !virt_addr_valid(dst_buf)) {
325 WARN_ON(1);
326 hmdfs_err("encrypt address is invalid");
327 return -EPERM;
328 }
329
330 get_random_bytes(cipher_iv, HMDFS_IV_SIZE);
331 memcpy(dst_buf, cipher_iv, HMDFS_IV_SIZE);
332 req = aead_request_alloc(con->tfm, GFP_KERNEL);
333 if (!req) {
334 hmdfs_err("aead_request_alloc() failed");
335 return -ENOMEM;
336 }
337 ret = set_aeadcipher(con->tfm, req, &result);
338 if (ret) {
339 hmdfs_err("set_enaeadcipher exit fault");
340 goto out;
341 }
342
343 sg_init_one(&src, src_buf, src_len);
344 sg_init_one(&dst, dst_buf + HMDFS_IV_SIZE, dst_len - HMDFS_IV_SIZE);
345 aead_request_set_crypt(req, &src, &dst, src_len, cipher_iv);
346 aead_request_set_ad(req, 0);
347 ret = aeadcipher_en_de(req, result, ENCRYPT_FLAG);
348 out:
349 aead_request_free(req);
350 return ret;
351 }
352
aeadcipher_decrypt_buffer(struct connection * con,__u8 * src_buf,size_t src_len,__u8 * dst_buf,size_t dst_len)353 int aeadcipher_decrypt_buffer(struct connection *con, __u8 *src_buf,
354 size_t src_len, __u8 *dst_buf, size_t dst_len)
355 {
356 int ret = 0;
357 struct scatterlist src, dst;
358 struct aead_request *req = NULL;
359 struct aeadcrypt_result result;
360 __u8 cipher_iv[HMDFS_IV_SIZE];
361
362 if (src_len <= HMDFS_IV_SIZE + HMDFS_TAG_SIZE)
363 return -EINVAL;
364 if (!virt_addr_valid(src_buf) || !virt_addr_valid(dst_buf)) {
365 WARN_ON(1);
366 hmdfs_err("decrypt address is invalid");
367 return -EPERM;
368 }
369
370 memcpy(cipher_iv, src_buf, HMDFS_IV_SIZE);
371 req = aead_request_alloc(con->tfm, GFP_KERNEL);
372 if (!req) {
373 hmdfs_err("aead_request_alloc() failed");
374 return -ENOMEM;
375 }
376 ret = set_aeadcipher(con->tfm, req, &result);
377 if (ret) {
378 hmdfs_err("set_deaeadcipher exit fault");
379 goto out;
380 }
381
382 sg_init_one(&src, src_buf + HMDFS_IV_SIZE, src_len - HMDFS_IV_SIZE);
383 sg_init_one(&dst, dst_buf, dst_len);
384 aead_request_set_crypt(req, &src, &dst, src_len - HMDFS_IV_SIZE,
385 cipher_iv);
386 aead_request_set_ad(req, 0);
387 ret = aeadcipher_en_de(req, result, DECRYPT_FLAG);
388 out:
389 aead_request_free(req);
390 return ret;
391 }
392
tcp_recvbuffer_cipher(struct connection * connect,struct hmdfs_head_cmd * recv)393 static int tcp_recvbuffer_cipher(struct connection *connect,
394 struct hmdfs_head_cmd *recv)
395 {
396 int ret = 0;
397 struct tcp_handle *tcp = NULL;
398 size_t cipherbuffer_len;
399 __u8 *cipherbuffer = NULL;
400 size_t outlen = 0;
401 __u8 *outdata = NULL;
402 __u32 recv_len = le32_to_cpu(recv->data_len);
403
404 tcp = (struct tcp_handle *)(connect->connect_handle);
405 if (recv_len == sizeof(struct hmdfs_head_cmd))
406 goto out_recv_head;
407 else if (recv_len > sizeof(struct hmdfs_head_cmd) &&
408 recv_len <= ADAPTER_MESSAGE_LENGTH)
409 cipherbuffer_len = recv_len - sizeof(struct hmdfs_head_cmd) +
410 HMDFS_IV_SIZE + HMDFS_TAG_SIZE;
411 else
412 return -ENOMSG;
413 cipherbuffer = kzalloc(cipherbuffer_len, GFP_KERNEL);
414 if (!cipherbuffer) {
415 hmdfs_err("zalloc cipherbuffer error");
416 return -ESHUTDOWN;
417 }
418 outlen = cipherbuffer_len - HMDFS_IV_SIZE - HMDFS_TAG_SIZE;
419 outdata = kzalloc(outlen, GFP_KERNEL);
420 if (!outdata) {
421 hmdfs_err("encrypt zalloc outdata error");
422 kfree(cipherbuffer);
423 return -ESHUTDOWN;
424 }
425
426 ret = tcp_read_buffer_from_socket(tcp->sock, cipherbuffer,
427 cipherbuffer_len);
428 if (ret)
429 goto out_recv;
430 ret = aeadcipher_decrypt_buffer(connect, cipherbuffer, cipherbuffer_len,
431 outdata, outlen);
432 if (ret) {
433 hmdfs_err("decrypt_buf fail");
434 goto out_recv;
435 }
436 out_recv_head:
437 if (connect_recv_callback[connect->status]) {
438 connect_recv_callback[connect->status](connect, recv, outdata,
439 outlen);
440 } else {
441 kfree(outdata);
442 hmdfs_err("encypt callback NULL status %d", connect->status);
443 }
444 kfree(cipherbuffer);
445 return ret;
446 out_recv:
447 kfree(cipherbuffer);
448 kfree(outdata);
449 return ret;
450 }
451
tcp_recvbuffer_tls(struct connection * connect,struct hmdfs_head_cmd * recv)452 static int tcp_recvbuffer_tls(struct connection *connect,
453 struct hmdfs_head_cmd *recv)
454 {
455 int ret = 0;
456 struct tcp_handle *tcp = NULL;
457 size_t outlen;
458 __u8 *outdata = NULL;
459 __u32 recv_len = le32_to_cpu(recv->data_len);
460
461 tcp = (struct tcp_handle *)(connect->connect_handle);
462 outlen = recv_len - sizeof(struct hmdfs_head_cmd);
463 if (outlen == 0)
464 goto out_recv_head;
465
466 /*
467 * NOTE: Up to half of the allocated memory may be wasted due to
468 * the Internal Fragmentation, however the memory allocation times
469 * can be reduced and we don't have to adjust existing message
470 * transporting mechanism
471 */
472 outdata = kmalloc(outlen, GFP_KERNEL);
473 if (!outdata)
474 return -ESHUTDOWN;
475
476 ret = tcp_read_buffer_from_socket(tcp->sock, outdata, outlen);
477 if (ret) {
478 kfree(outdata);
479 return ret;
480 }
481 tcp->connect->stat.recv_bytes += outlen;
482 out_recv_head:
483 if (connect_recv_callback[connect->status]) {
484 connect_recv_callback[connect->status](connect, recv, outdata,
485 outlen);
486 } else {
487 kfree(outdata);
488 hmdfs_err("callback NULL status %d", connect->status);
489 }
490 return 0;
491 }
492
tcp_receive_from_sock(struct tcp_handle * tcp)493 static int tcp_receive_from_sock(struct tcp_handle *tcp)
494 {
495 struct hmdfs_head_cmd *recv = NULL;
496 int ret = 0;
497
498 if (!tcp) {
499 hmdfs_info("tcp recv thread !tcp");
500 return -ESHUTDOWN;
501 }
502
503 if (!tcp->sock) {
504 hmdfs_info("tcp recv thread !sock");
505 return -ESHUTDOWN;
506 }
507
508 recv = kmem_cache_alloc(tcp->recv_cache, GFP_KERNEL);
509 if (!recv) {
510 hmdfs_info("tcp recv thread !cache");
511 return -ESHUTDOWN;
512 }
513
514 ret = tcp_read_head_from_socket(tcp->sock, recv,
515 sizeof(struct hmdfs_head_cmd));
516 if (ret)
517 goto out;
518
519 tcp->connect->stat.recv_bytes += sizeof(struct hmdfs_head_cmd);
520 tcp->connect->stat.recv_message_count++;
521
522 if (recv->magic != HMDFS_MSG_MAGIC || recv->version != HMDFS_VERSION) {
523 hmdfs_info_ratelimited("tcp recv fd %d wrong magic. drop message",
524 tcp->fd);
525 goto out;
526 }
527
528 if ((le32_to_cpu(recv->data_len) >
529 HMDFS_MAX_MESSAGE_LEN + sizeof(struct hmdfs_head_cmd)) ||
530 (le32_to_cpu(recv->data_len) < sizeof(struct hmdfs_head_cmd))) {
531 hmdfs_info("tcp recv fd %d length error. drop message",
532 tcp->fd);
533 goto out;
534 }
535
536 if (tcp->connect->status == CONNECT_STAT_WORKING &&
537 recv->operations.command == F_READPAGE &&
538 recv->operations.cmd_flag == C_RESPONSE) {
539 ret = tcp_recvpage_tls(tcp->connect, recv);
540 goto out;
541 }
542
543 if (tcp->connect->status == CONNECT_STAT_WORKING)
544 ret = tcp_recvbuffer_tls(tcp->connect, recv);
545 else
546 ret = tcp_recvbuffer_cipher(tcp->connect, recv);
547
548 out:
549 kmem_cache_free(tcp->recv_cache, recv);
550 return ret;
551 }
552
tcp_handle_is_available(struct tcp_handle * tcp)553 static bool tcp_handle_is_available(struct tcp_handle *tcp)
554 {
555 #ifdef CONFIG_HMDFS_FS_ENCRYPTION
556 struct tls_context *tls_ctx = NULL;
557 struct tls_sw_context_rx *ctx = NULL;
558
559 #endif
560 if (!tcp || !tcp->sock || !tcp->sock->sk) {
561 hmdfs_err("Invalid tcp connection");
562 return false;
563 }
564
565 if (tcp->sock->sk->sk_state != TCP_ESTABLISHED) {
566 hmdfs_err("TCP conn %d is broken, current sk_state is %d",
567 tcp->fd, tcp->sock->sk->sk_state);
568 return false;
569 }
570
571 if (tcp->sock->state != SS_CONNECTING &&
572 tcp->sock->state != SS_CONNECTED) {
573 hmdfs_err("TCP conn %d is broken, current sock state is %d",
574 tcp->fd, tcp->sock->state);
575 return false;
576 }
577
578 #ifdef CONFIG_HMDFS_FS_ENCRYPTION
579 tls_ctx = tls_get_ctx(tcp->sock->sk);
580 if (tls_ctx) {
581 ctx = tls_sw_ctx_rx(tls_ctx);
582 if (ctx && ctx->strp.stopped) {
583 hmdfs_err(
584 "TCP conn %d is broken, the strparser has stopped",
585 tcp->fd);
586 return false;
587 }
588 }
589 #endif
590 return true;
591 }
592
tcp_recv_thread(void * arg)593 static int tcp_recv_thread(void *arg)
594 {
595 int ret = 0;
596 struct tcp_handle *tcp = (struct tcp_handle *)arg;
597 const struct cred *old_cred;
598
599 WARN_ON(!tcp);
600 WARN_ON(!tcp->sock);
601 set_freezable();
602
603 old_cred = hmdfs_override_creds(tcp->connect->node->sbi->system_cred);
604
605 while (!kthread_should_stop()) {
606 /*
607 * 1. In case the redundant connection has not been mounted on
608 * a peer
609 * 2. Lock is unnecessary since a transient state is acceptable
610 */
611 if (tcp_handle_is_available(tcp) &&
612 list_empty(&tcp->connect->list))
613 goto freeze;
614 if (!mutex_trylock(&tcp->close_mutex))
615 continue;
616 if (tcp_handle_is_available(tcp))
617 ret = tcp_receive_from_sock(tcp);
618 else
619 ret = -ESHUTDOWN;
620 /*
621 * This kthread will exit if ret is -ESHUTDOWN, thus we need to
622 * set recv_task to NULL to avoid calling kthread_stop() from
623 * tcp_close_socket().
624 */
625 if (ret == -ESHUTDOWN)
626 tcp->recv_task = NULL;
627 mutex_unlock(&tcp->close_mutex);
628 if (ret == -ESHUTDOWN) {
629 hmdfs_node_inc_evt_seq(tcp->connect->node);
630 tcp->connect->status = CONNECT_STAT_STOP;
631 if (tcp->connect->node->status != NODE_STAT_OFFLINE)
632 hmdfs_reget_connection(tcp->connect);
633 break;
634 }
635 freeze:
636 schedule();
637 try_to_freeze();
638 }
639
640 hmdfs_info("Exiting. Now, sock state = %d", tcp->sock->state);
641 hmdfs_revert_creds(old_cred);
642 connection_put(tcp->connect);
643 return 0;
644 }
645
tcp_send_message_sock_cipher(struct tcp_handle * tcp,struct hmdfs_send_data * msg)646 static int tcp_send_message_sock_cipher(struct tcp_handle *tcp,
647 struct hmdfs_send_data *msg)
648 {
649 int ret = 0;
650 __u8 *outdata = NULL;
651 size_t outlen = 0;
652 int send_len = 0;
653 int send_vec_cnt = 0;
654 struct msghdr tcp_msg;
655 struct kvec iov[TCP_KVEC_ELE_DOUBLE];
656
657 memset(&tcp_msg, 0, sizeof(tcp_msg));
658 if (!tcp || !tcp->sock) {
659 hmdfs_err("encrypt tcp socket = NULL");
660 return -ESHUTDOWN;
661 }
662 iov[0].iov_base = msg->head;
663 iov[0].iov_len = msg->head_len;
664 send_vec_cnt = TCP_KVEC_HEAD;
665 if (msg->len == 0)
666 goto send;
667
668 outlen = msg->len + HMDFS_IV_SIZE + HMDFS_TAG_SIZE;
669 outdata = kzalloc(outlen, GFP_KERNEL);
670 if (!outdata) {
671 hmdfs_err("tcp send message encrypt fail to alloc outdata");
672 return -ENOMEM;
673 }
674 ret = aeadcipher_encrypt_buffer(tcp->connect, msg->data, msg->len,
675 outdata, outlen);
676 if (ret) {
677 hmdfs_err("encrypt_buf fail");
678 goto out;
679 }
680 iov[1].iov_base = outdata;
681 iov[1].iov_len = outlen;
682 send_vec_cnt = TCP_KVEC_ELE_DOUBLE;
683 send:
684 mutex_lock(&tcp->send_mutex);
685 send_len = sendmsg_nofs(tcp->sock, &tcp_msg, iov, send_vec_cnt,
686 msg->head_len + outlen);
687 mutex_unlock(&tcp->send_mutex);
688 if (send_len <= 0) {
689 hmdfs_err("error %d", send_len);
690 ret = -ESHUTDOWN;
691 } else if (send_len != msg->head_len + outlen) {
692 hmdfs_err("send part of message. %d/%zu", send_len,
693 msg->head_len + outlen);
694 ret = -EAGAIN;
695 } else {
696 ret = 0;
697 }
698 out:
699 kfree(outdata);
700 return ret;
701 }
702
tcp_send_message_sock_tls(struct tcp_handle * tcp,struct hmdfs_send_data * msg)703 static int tcp_send_message_sock_tls(struct tcp_handle *tcp,
704 struct hmdfs_send_data *msg)
705 {
706 int send_len = 0;
707 int send_vec_cnt = 0;
708 struct msghdr tcp_msg;
709 struct kvec iov[TCP_KVEC_ELE_TRIPLE];
710
711 memset(&tcp_msg, 0, sizeof(tcp_msg));
712 if (!tcp || !tcp->sock) {
713 hmdfs_err("tcp socket = NULL");
714 return -ESHUTDOWN;
715 }
716 iov[TCP_KVEC_HEAD].iov_base = msg->head;
717 iov[TCP_KVEC_HEAD].iov_len = msg->head_len;
718 if (msg->len == 0 && msg->sdesc_len == 0) {
719 send_vec_cnt = TCP_KVEC_ELE_SINGLE;
720 } else if (msg->sdesc_len == 0) {
721 iov[TCP_KVEC_DATA].iov_base = msg->data;
722 iov[TCP_KVEC_DATA].iov_len = msg->len;
723 send_vec_cnt = TCP_KVEC_ELE_DOUBLE;
724 } else {
725 iov[TCP_KVEC_FILE_PARA].iov_base = msg->sdesc;
726 iov[TCP_KVEC_FILE_PARA].iov_len = msg->sdesc_len;
727 iov[TCP_KVEC_FILE_CONTENT].iov_base = msg->data;
728 iov[TCP_KVEC_FILE_CONTENT].iov_len = msg->len;
729 send_vec_cnt = TCP_KVEC_ELE_TRIPLE;
730 }
731 mutex_lock(&tcp->send_mutex);
732 send_len = sendmsg_nofs(tcp->sock, &tcp_msg, iov, send_vec_cnt,
733 msg->head_len + msg->len + msg->sdesc_len);
734 mutex_unlock(&tcp->send_mutex);
735 if (send_len == -EBADMSG) {
736 return -EBADMSG;
737 } else if (send_len <= 0) {
738 hmdfs_err("error %d", send_len);
739 return -ESHUTDOWN;
740 } else if (send_len != msg->head_len + msg->len + msg->sdesc_len) {
741 hmdfs_err("send part of message. %d/%zu", send_len,
742 msg->head_len + msg->len);
743 tcp->connect->stat.send_bytes += send_len;
744 return -EAGAIN;
745 }
746 tcp->connect->stat.send_bytes += send_len;
747 tcp->connect->stat.send_message_count++;
748 return 0;
749 }
750
751 #ifdef CONFIG_HMDFS_FS_ENCRYPTION
tcp_send_rekey_request(struct connection * connect)752 int tcp_send_rekey_request(struct connection *connect)
753 {
754 int ret = 0;
755 struct hmdfs_send_data msg;
756 struct tcp_handle *tcp = connect->connect_handle;
757 struct hmdfs_head_cmd *head = NULL;
758 struct connection_rekey_request *rekey_request_param = NULL;
759 struct hmdfs_cmd operations;
760
761 hmdfs_init_cmd(&operations, F_CONNECT_REKEY);
762 head = kzalloc(sizeof(struct hmdfs_head_cmd) +
763 sizeof(struct connection_rekey_request),
764 GFP_KERNEL);
765 if (!head)
766 return -ENOMEM;
767 rekey_request_param =
768 (struct connection_rekey_request
769 *)((uint8_t *)head + sizeof(struct hmdfs_head_cmd));
770
771 rekey_request_param->update_request = cpu_to_le32(UPDATE_NOT_REQUESTED);
772
773 head->magic = HMDFS_MSG_MAGIC;
774 head->version = HMDFS_VERSION;
775 head->operations = operations;
776 head->data_len =
777 cpu_to_le32(sizeof(*head) + sizeof(*rekey_request_param));
778 head->reserved = 0;
779 head->reserved1 = 0;
780 head->ret_code = 0;
781
782 msg.head = head;
783 msg.head_len = sizeof(*head);
784 msg.data = rekey_request_param;
785 msg.len = sizeof(*rekey_request_param);
786 msg.sdesc = NULL;
787 msg.sdesc_len = 0;
788 ret = tcp_send_message_sock_tls(tcp, &msg);
789 if (ret != 0)
790 hmdfs_err("return error %d", ret);
791 kfree(head);
792 return ret;
793 }
794 #endif
795
tcp_send_message(struct connection * connect,struct hmdfs_send_data * msg)796 static int tcp_send_message(struct connection *connect,
797 struct hmdfs_send_data *msg)
798 {
799 int ret = 0;
800 #ifdef CONFIG_HMDFS_FS_ENCRYPTION
801 unsigned long nowtime = jiffies;
802 #endif
803 struct tcp_handle *tcp = NULL;
804
805 if (!connect) {
806 hmdfs_err("tcp connection = NULL ");
807 return -ESHUTDOWN;
808 }
809 if (!msg) {
810 hmdfs_err("msg = NULL");
811 return -EINVAL;
812 }
813 if (msg->len > HMDFS_MAX_MESSAGE_LEN) {
814 hmdfs_err("message->len error: %zu", msg->len);
815 return -EINVAL;
816 }
817 tcp = (struct tcp_handle *)(connect->connect_handle);
818 if (connect->status == CONNECT_STAT_STOP)
819 return -EAGAIN;
820
821 trace_hmdfs_tcp_send_message(msg->head);
822
823 if (connect->status == CONNECT_STAT_WORKING)
824 ret = tcp_send_message_sock_tls(tcp, msg);
825 else
826 ret = tcp_send_message_sock_cipher(tcp, msg);
827
828 if (ret != 0) {
829 hmdfs_err("return error %d", ret);
830 return ret;
831 }
832 #ifdef CONFIG_HMDFS_FS_ENCRYPTION
833 if (nowtime - connect->stat.rekey_time >= REKEY_LIFETIME &&
834 connect->status == CONNECT_STAT_WORKING) {
835 hmdfs_info("send rekey message to devid %llu",
836 connect->node->device_id);
837 ret = tcp_send_rekey_request(connect);
838 if (ret == 0)
839 set_crypto_info(connect, SET_CRYPTO_SEND);
840 connect->stat.rekey_time = nowtime;
841 }
842 #endif
843 return ret;
844 }
845
tcp_close_socket(struct tcp_handle * tcp)846 void tcp_close_socket(struct tcp_handle *tcp)
847 {
848 int ret;
849 if (!tcp)
850 return;
851 mutex_lock(&tcp->close_mutex);
852 if (tcp->recv_task) {
853 ret = kthread_stop(tcp->recv_task);
854 /* recv_task killed before sched, we need to put the connect */
855 if (ret == -EINTR)
856 connection_put(tcp->connect);
857 tcp->recv_task = NULL;
858 }
859 mutex_unlock(&tcp->close_mutex);
860 }
861
set_tfm(__u8 * master_key,struct crypto_aead * tfm)862 static int set_tfm(__u8 *master_key, struct crypto_aead *tfm)
863 {
864 int ret = 0;
865 int iv_len;
866 __u8 *sec_key = NULL;
867
868 sec_key = master_key;
869 crypto_aead_clear_flags(tfm, ~0);
870 ret = crypto_aead_setkey(tfm, sec_key, HMDFS_KEY_SIZE);
871 if (ret) {
872 hmdfs_err("failed to set the key");
873 goto out;
874 }
875 ret = crypto_aead_setauthsize(tfm, HMDFS_TAG_SIZE);
876 if (ret) {
877 hmdfs_err("authsize length is error");
878 goto out;
879 }
880
881 iv_len = crypto_aead_ivsize(tfm);
882 if (iv_len != HMDFS_IV_SIZE) {
883 hmdfs_err("IV recommended value should be set %d", iv_len);
884 ret = -ENODATA;
885 }
886 out:
887 return ret;
888 }
889
is_tcp_socket(struct tcp_handle * tcp)890 static bool is_tcp_socket(struct tcp_handle *tcp)
891 {
892 struct inet_connection_sock *icsk;
893
894 if (!tcp || !tcp->sock || !tcp->sock->sk) {
895 hmdfs_err("invalid tcp handle");
896 return false;
897 }
898
899 if (tcp->sock->sk->sk_protocol != IPPROTO_TCP) {
900 hmdfs_err("invalid socket protocol");
901 return false;
902 }
903
904 lock_sock(tcp->sock->sk);
905 icsk = inet_csk(tcp->sock->sk);
906 if (icsk->icsk_ulp_ops) {
907 hmdfs_err("ulp not NULL");
908 release_sock(tcp->sock->sk);
909 return false;
910 }
911
912 release_sock(tcp->sock->sk);
913 return true;
914 }
915
tcp_update_socket(struct tcp_handle * tcp,int fd,uint8_t * master_key,struct socket * socket)916 static int tcp_update_socket(struct tcp_handle *tcp, int fd,
917 uint8_t *master_key, struct socket *socket)
918 {
919 int err = 0;
920 struct hmdfs_peer *node = NULL;
921
922 if (!master_key || fd == 0)
923 return -EAGAIN;
924
925 tcp->sock = socket;
926 tcp->fd = fd;
927
928 if (!is_tcp_socket(tcp)) {
929 err = -EINVAL;
930 goto put_sock;
931 }
932
933 if (!tcp_handle_is_available(tcp)) {
934 err = -EPIPE;
935 goto put_sock;
936 }
937
938 hmdfs_info("socket fd %d, state %d, refcount %ld protocol %d", fd,
939 socket->state, file_count(socket->file),
940 socket->sk->sk_protocol);
941
942 tcp->recv_cache = kmem_cache_create("hmdfs_socket",
943 tcp->recvbuf_maxsize,
944 0, SLAB_HWCACHE_ALIGN, NULL);
945 if (!tcp->recv_cache) {
946 err = -ENOMEM;
947 goto put_sock;
948 }
949
950 err = tcp_set_recvtimeo(socket, TCP_RECV_TIMEOUT);
951 if (err) {
952 hmdfs_err("tcp set timeout error");
953 goto free_mem_cache;
954 }
955
956 /* send key and recv key, default MASTER KEY */
957 memcpy(tcp->connect->master_key, master_key, HMDFS_KEY_SIZE);
958 memcpy(tcp->connect->send_key, master_key, HMDFS_KEY_SIZE);
959 memcpy(tcp->connect->recv_key, master_key, HMDFS_KEY_SIZE);
960 tcp->connect->tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
961 if (IS_ERR(tcp->connect->tfm)) {
962 err = PTR_ERR(tcp->connect->tfm);
963 tcp->connect->tfm = NULL;
964 hmdfs_err("failed to load transform for gcm(aes):%d", err);
965 goto free_mem_cache;
966 }
967
968 err = set_tfm(master_key, tcp->connect->tfm);
969 if (err) {
970 hmdfs_err("tfm seting exit fault");
971 goto free_crypto;
972 }
973
974 connection_get(tcp->connect);
975
976 node = tcp->connect->node;
977 tcp->recv_task = kthread_create(tcp_recv_thread, (void *)tcp,
978 "dfs_rcv%u_%llu_%d",
979 node->owner, node->device_id, fd);
980 if (IS_ERR(tcp->recv_task)) {
981 err = PTR_ERR(tcp->recv_task);
982 hmdfs_err("tcp->rcev_task %d", err);
983 goto put_conn;
984 }
985
986 return 0;
987
988 put_conn:
989 tcp->recv_task = NULL;
990 connection_put(tcp->connect);
991 free_crypto:
992 crypto_free_aead(tcp->connect->tfm);
993 tcp->connect->tfm = NULL;
994 free_mem_cache:
995 kmem_cache_destroy(tcp->recv_cache);
996 tcp->recv_cache = NULL;
997 put_sock:
998 tcp->sock = NULL;
999 tcp->fd = 0;
1000
1001 return err;
1002 }
1003
tcp_alloc_handle(struct connection * connect,int socket_fd,uint8_t * master_key,struct socket * socket)1004 static struct tcp_handle *tcp_alloc_handle(struct connection *connect,
1005 int socket_fd, uint8_t *master_key, struct socket *socket)
1006 {
1007 int ret = 0;
1008 struct tcp_handle *tcp = kzalloc(sizeof(*tcp), GFP_KERNEL);
1009
1010 if (!tcp)
1011 return NULL;
1012 tcp->connect = connect;
1013 tcp->connect->connect_handle = (void *)tcp;
1014 tcp->recvbuf_maxsize = MAX_RECV_SIZE;
1015 tcp->recv_task = NULL;
1016 tcp->recv_cache = NULL;
1017 tcp->sock = NULL;
1018 mutex_init(&tcp->close_mutex);
1019 mutex_init(&tcp->send_mutex);
1020 ret = tcp_update_socket(tcp, socket_fd, master_key, socket);
1021 if (ret) {
1022 kfree(tcp);
1023 return NULL;
1024 }
1025 return tcp;
1026 }
1027
hmdfs_get_connection(struct hmdfs_peer * peer)1028 void hmdfs_get_connection(struct hmdfs_peer *peer)
1029 {
1030 struct notify_param param;
1031
1032 if (!peer)
1033 return;
1034 param.notify = NOTIFY_GET_SESSION;
1035 param.fd = INVALID_SOCKET_FD;
1036 memcpy(param.remote_cid, peer->cid, HMDFS_CID_SIZE);
1037 notify(peer, ¶m);
1038 }
1039
connection_notify_to_close(struct connection * conn)1040 static void connection_notify_to_close(struct connection *conn)
1041 {
1042 struct notify_param param;
1043 struct hmdfs_peer *peer = NULL;
1044 struct tcp_handle *tcp = NULL;
1045
1046 tcp = conn->connect_handle;
1047 peer = conn->node;
1048
1049 // libdistbus/src/TcpSession.cpp will close the socket
1050 param.notify = NOTIFY_GET_SESSION;
1051 param.fd = tcp->fd;
1052 memcpy(param.remote_cid, peer->cid, HMDFS_CID_SIZE);
1053 notify(peer, ¶m);
1054 }
1055
hmdfs_reget_connection(struct connection * conn)1056 void hmdfs_reget_connection(struct connection *conn)
1057 {
1058 struct tcp_handle *tcp = NULL;
1059 struct connection *conn_impl = NULL;
1060 struct connection *next = NULL;
1061 struct task_struct *recv_task = NULL;
1062 bool should_put = false;
1063 bool stop_thread = true;
1064
1065 if (!conn)
1066 return;
1067
1068 // One may put a connection if and only if he took it out of the list
1069 mutex_lock(&conn->node->conn_impl_list_lock);
1070 list_for_each_entry_safe(conn_impl, next, &conn->node->conn_impl_list,
1071 list) {
1072 if (conn_impl == conn) {
1073 should_put = true;
1074 list_move(&conn->list, &conn->node->conn_deleting_list);
1075 break;
1076 }
1077 }
1078 if (!should_put) {
1079 mutex_unlock(&conn->node->conn_impl_list_lock);
1080 return;
1081 }
1082
1083 tcp = conn->connect_handle;
1084 if (tcp) {
1085 recv_task = tcp->recv_task;
1086 /*
1087 * To avoid the receive thread to stop itself. Ensure receive
1088 * thread stop before process offline event
1089 */
1090 if (!recv_task || recv_task->pid == current->pid)
1091 stop_thread = false;
1092 }
1093 mutex_unlock(&conn->node->conn_impl_list_lock);
1094
1095 if (tcp) {
1096 if (tcp->sock) {
1097 hmdfs_info("shudown sock: fd = %d, sockref = %ld, connref = %u stop_thread = %d",
1098 tcp->fd, file_count(tcp->sock->file),
1099 kref_read(&conn->ref_cnt), stop_thread);
1100 kernel_sock_shutdown(tcp->sock, SHUT_RDWR);
1101 }
1102
1103 if (stop_thread)
1104 tcp_close_socket(tcp);
1105
1106 if (tcp->fd != INVALID_SOCKET_FD)
1107 connection_notify_to_close(conn);
1108 }
1109 connection_put(conn);
1110 }
1111
1112 static struct connection *
lookup_conn_by_socketfd_unsafe(struct hmdfs_peer * node,struct socket * socket)1113 lookup_conn_by_socketfd_unsafe(struct hmdfs_peer *node, struct socket *socket)
1114 {
1115 struct connection *tcp_conn = NULL;
1116 struct tcp_handle *tcp = NULL;
1117
1118 list_for_each_entry(tcp_conn, &node->conn_impl_list, list) {
1119 if (tcp_conn->connect_handle) {
1120 tcp = (struct tcp_handle *)(tcp_conn->connect_handle);
1121 if (tcp->sock == socket) {
1122 connection_get(tcp_conn);
1123 return tcp_conn;
1124 }
1125 }
1126 }
1127 return NULL;
1128 }
1129
hmdfs_reget_connection_work_fn(struct work_struct * work)1130 static void hmdfs_reget_connection_work_fn(struct work_struct *work)
1131 {
1132 struct connection *conn =
1133 container_of(work, struct connection, reget_work);
1134
1135 hmdfs_reget_connection(conn);
1136 connection_put(conn);
1137 }
1138
alloc_conn_tcp(struct hmdfs_peer * node,int socket_fd,uint8_t * master_key,uint8_t status,struct socket * socket)1139 struct connection *alloc_conn_tcp(struct hmdfs_peer *node, int socket_fd,
1140 uint8_t *master_key, uint8_t status, struct socket *socket)
1141 {
1142 struct connection *tcp_conn = NULL;
1143 unsigned long nowtime = jiffies;
1144
1145 tcp_conn = kzalloc(sizeof(*tcp_conn), GFP_KERNEL);
1146 if (!tcp_conn)
1147 goto out_err;
1148
1149 kref_init(&tcp_conn->ref_cnt);
1150 mutex_init(&tcp_conn->ref_lock);
1151 INIT_LIST_HEAD(&tcp_conn->list);
1152 tcp_conn->node = node;
1153 tcp_conn->close = tcp_stop_connect;
1154 tcp_conn->send_message = tcp_send_message;
1155 tcp_conn->type = CONNECT_TYPE_TCP;
1156 tcp_conn->status = status;
1157 tcp_conn->stat.rekey_time = nowtime;
1158 tcp_conn->connect_handle =
1159 (void *)tcp_alloc_handle(tcp_conn, socket_fd, master_key, socket);
1160 INIT_WORK(&tcp_conn->reget_work, hmdfs_reget_connection_work_fn);
1161 if (!tcp_conn->connect_handle) {
1162 hmdfs_err("Failed to alloc tcp_handle for strcut conn");
1163 goto out_err;
1164 }
1165 return tcp_conn;
1166
1167 out_err:
1168 kfree(tcp_conn);
1169 return NULL;
1170 }
1171
add_conn_tcp_unsafe(struct hmdfs_peer * node,struct socket * socket,struct connection * conn2add)1172 static struct connection *add_conn_tcp_unsafe(struct hmdfs_peer *node,
1173 struct socket *socket,
1174 struct connection *conn2add)
1175 {
1176 struct connection *conn;
1177
1178 conn = lookup_conn_by_socketfd_unsafe(node, socket);
1179 if (conn) {
1180 hmdfs_info("socket already in list");
1181 return conn;
1182 }
1183
1184 /* Prefer to use socket opened by local device */
1185 if (conn2add->status == CONNECT_STAT_WAIT_REQUEST)
1186 list_add(&conn2add->list, &node->conn_impl_list);
1187 else
1188 list_add_tail(&conn2add->list, &node->conn_impl_list);
1189 connection_get(conn2add);
1190 return conn2add;
1191 }
1192
hmdfs_get_conn_tcp(struct hmdfs_peer * node,int fd,uint8_t * master_key,uint8_t status)1193 struct connection *hmdfs_get_conn_tcp(struct hmdfs_peer *node, int fd,
1194 uint8_t *master_key, uint8_t status)
1195 {
1196 struct connection *tcp_conn = NULL, *on_peer_conn = NULL;
1197 struct tcp_handle *tcp = NULL;
1198 struct socket *socket = NULL;
1199 int err = 0;
1200
1201 socket = sockfd_lookup(fd, &err);
1202 if (!socket) {
1203 hmdfs_err("lookup socket fail, socket_fd %d, err %d", fd, err);
1204 return NULL;
1205 }
1206 mutex_lock(&node->conn_impl_list_lock);
1207 tcp_conn = lookup_conn_by_socketfd_unsafe(node, socket);
1208 mutex_unlock(&node->conn_impl_list_lock);
1209 if (tcp_conn) {
1210 hmdfs_info("Got a existing tcp conn: fsocket_fd = %d",
1211 fd);
1212 sockfd_put(socket);
1213 goto out;
1214 }
1215
1216 tcp_conn = alloc_conn_tcp(node, fd, master_key, status, socket);
1217 if (!tcp_conn) {
1218 hmdfs_info("Failed to alloc a tcp conn, socket_fd %d", fd);
1219 sockfd_put(socket);
1220 goto out;
1221 }
1222
1223 mutex_lock(&node->conn_impl_list_lock);
1224 on_peer_conn = add_conn_tcp_unsafe(node, socket, tcp_conn);
1225 mutex_unlock(&node->conn_impl_list_lock);
1226 tcp = tcp_conn->connect_handle;
1227 if (on_peer_conn == tcp_conn) {
1228 hmdfs_info("Got a newly allocated tcp conn: socket_fd = %d", fd);
1229 wake_up_process(tcp->recv_task);
1230 if (status == CONNECT_STAT_WAIT_RESPONSE)
1231 connection_send_handshake(
1232 on_peer_conn, CONNECT_MESG_HANDSHAKE_REQUEST,
1233 0);
1234 } else {
1235 hmdfs_info("Got a existing tcp conn: socket_fd = %d", fd);
1236 tcp->fd = INVALID_SOCKET_FD;
1237 tcp_close_socket(tcp);
1238 connection_put(tcp_conn);
1239
1240 tcp_conn = on_peer_conn;
1241 }
1242
1243 out:
1244 return tcp_conn;
1245 }
1246
tcp_stop_connect(struct connection * connect)1247 void tcp_stop_connect(struct connection *connect)
1248 {
1249 hmdfs_info("now nothing to do");
1250 }
1251