2 * Copyright (C) 2012 David Goulet <dgoulet@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
11 #include <common/common.hpp>
12 #include <common/compat/errno.hpp>
13 #include <common/compat/time.hpp>
14 #include <common/time.hpp>
24 #include <sys/types.h>
27 #define RECONNECT_DELAY 200 /* ms */
30 * INET protocol operations.
32 static const struct lttcomm_proto_ops inet_ops
= {
33 .bind
= lttcomm_bind_inet_sock
,
34 .close
= lttcomm_close_inet_sock
,
35 .connect
= lttcomm_connect_inet_sock
,
36 .accept
= lttcomm_accept_inet_sock
,
37 .listen
= lttcomm_listen_inet_sock
,
38 .recvmsg
= lttcomm_recvmsg_inet_sock
,
39 .sendmsg
= lttcomm_sendmsg_inet_sock
,
42 unsigned long lttcomm_inet_tcp_timeout
;
45 * Creates an PF_INET socket.
47 int lttcomm_create_inet_sock(struct lttcomm_sock
*sock
, int type
, int proto
)
50 unsigned long timeout
;
52 /* Create server socket */
53 if ((sock
->fd
= socket(PF_INET
, type
, proto
)) < 0) {
54 PERROR("socket inet");
58 sock
->ops
= &inet_ops
;
61 * Set socket option to reuse the address.
63 ret
= setsockopt(sock
->fd
, SOL_SOCKET
, SO_REUSEADDR
, &val
, sizeof(int));
65 PERROR("setsockopt inet");
68 timeout
= lttcomm_get_network_timeout();
70 ret
= lttcomm_setsockopt_rcv_timeout(sock
->fd
, timeout
);
74 ret
= lttcomm_setsockopt_snd_timeout(sock
->fd
, timeout
);
87 * Bind socket and return.
89 int lttcomm_bind_inet_sock(struct lttcomm_sock
*sock
)
91 struct sockaddr_in sockaddr
= sock
->sockaddr
.addr
.sin
;
93 return bind(sock
->fd
, (struct sockaddr
*) &sockaddr
, sizeof(sockaddr
));
96 static int connect_no_timeout(struct lttcomm_sock
*sock
)
98 struct sockaddr_in sockaddr
= sock
->sockaddr
.addr
.sin
;
100 return connect(sock
->fd
, (struct sockaddr
*) &sockaddr
, sizeof(sockaddr
));
103 static int connect_with_timeout(struct lttcomm_sock
*sock
)
105 unsigned long timeout
= lttcomm_get_network_timeout();
106 int ret
, flags
, connect_ret
;
107 struct timespec orig_time
, cur_time
;
108 unsigned long diff_ms
;
109 struct sockaddr_in sockaddr
;
111 ret
= fcntl(sock
->fd
, F_GETFL
, 0);
118 /* Set socket to nonblock */
119 ret
= fcntl(sock
->fd
, F_SETFL
, flags
| O_NONBLOCK
);
125 ret
= lttng_clock_gettime(CLOCK_MONOTONIC
, &orig_time
);
127 PERROR("clock_gettime");
131 sockaddr
= sock
->sockaddr
.addr
.sin
;
132 connect_ret
= connect(sock
->fd
, (struct sockaddr
*) &sockaddr
, sizeof(sockaddr
));
133 if (connect_ret
== -1 && errno
!= EAGAIN
&& errno
!= EWOULDBLOCK
&& errno
!= EINPROGRESS
) {
135 } else if (!connect_ret
) {
136 /* Connect succeeded */
140 DBG("Asynchronous connect for sock %d, performing polling with"
145 * Perform poll loop following EINPROGRESS recommendation from
146 * connect(2) man page.
152 fds
.events
= POLLOUT
;
154 ret
= poll(&fds
, 1, RECONNECT_DELAY
);
157 } else if (ret
> 0) {
159 socklen_t optval_len
= sizeof(optval
);
161 if (!(fds
.revents
& POLLOUT
)) {
162 /* Either hup or error */
167 ret
= getsockopt(sock
->fd
, SOL_SOCKET
, SO_ERROR
, &optval
, &optval_len
);
169 PERROR("getsockopt");
176 /* Get actual connect() errno from opt_val */
181 /* ret == 0: timeout */
182 ret
= lttng_clock_gettime(CLOCK_MONOTONIC
, &cur_time
);
184 PERROR("clock_gettime");
188 if (timespec_to_ms(timespec_abs_diff(cur_time
, orig_time
), &diff_ms
) < 0) {
189 ERR("timespec_to_ms input overflows milliseconds output");
193 } while (diff_ms
< timeout
);
200 /* Restore initial flags */
201 ret
= fcntl(sock
->fd
, F_SETFL
, flags
);
204 /* Continue anyway */
211 * Connect PF_INET socket.
213 int lttcomm_connect_inet_sock(struct lttcomm_sock
*sock
)
217 if (lttcomm_get_network_timeout()) {
218 ret
= connect_with_timeout(sock
);
220 ret
= connect_no_timeout(sock
);
230 closeret
= close(sock
->fd
);
232 PERROR("close inet");
239 * Do an accept(2) on the sock and return the new lttcomm socket. The socket
240 * MUST be bind(2) before.
242 struct lttcomm_sock
*lttcomm_accept_inet_sock(struct lttcomm_sock
*sock
)
246 struct lttcomm_sock
*new_sock
;
247 unsigned long timeout
;
248 struct sockaddr_in new_addr
= {};
250 if (sock
->proto
== LTTCOMM_SOCK_UDP
) {
252 * accept(2) does not exist for UDP so simply return the passed socket.
258 new_sock
= lttcomm_alloc_sock(sock
->proto
);
259 if (new_sock
== nullptr) {
263 len
= sizeof(new_addr
);
266 new_fd
= accept(sock
->fd
, (struct sockaddr
*) &new_addr
, &len
);
268 PERROR("accept inet");
271 new_sock
->sockaddr
.addr
.sin
= new_addr
;
272 timeout
= lttcomm_get_network_timeout();
276 ret
= lttcomm_setsockopt_rcv_timeout(new_fd
, timeout
);
280 ret
= lttcomm_setsockopt_snd_timeout(new_fd
, timeout
);
286 new_sock
->fd
= new_fd
;
287 new_sock
->ops
= &inet_ops
;
293 if (close(new_fd
) < 0) {
294 PERROR("accept inet close fd");
303 * Make the socket listen using LTTNG_SESSIOND_COMM_MAX_LISTEN.
305 int lttcomm_listen_inet_sock(struct lttcomm_sock
*sock
, int backlog
)
309 if (sock
->proto
== LTTCOMM_SOCK_UDP
) {
310 /* listen(2) does not exist for UDP so simply return success. */
315 /* Default listen backlog */
317 backlog
= LTTNG_SESSIOND_COMM_MAX_LISTEN
;
320 ret
= listen(sock
->fd
, backlog
);
322 PERROR("listen inet");
330 * Receive data of size len in put that data into the buf param. Using recvmsg
333 * Return the size of received data.
335 ssize_t
lttcomm_recvmsg_inet_sock(struct lttcomm_sock
*sock
, void *buf
, size_t len
, int flags
)
341 struct sockaddr_in addr
= sock
->sockaddr
.addr
.sin
;
343 memset(&msg
, 0, sizeof(msg
));
345 iov
[0].iov_base
= buf
;
346 iov
[0].iov_len
= len
;
350 msg
.msg_name
= (struct sockaddr
*) &addr
;
351 msg
.msg_namelen
= sizeof(sock
->sockaddr
.addr
.sin
);
354 len_last
= iov
[0].iov_len
;
355 ret
= recvmsg(sock
->fd
, &msg
, flags
);
357 if (flags
& MSG_DONTWAIT
) {
360 iov
[0].iov_base
= ((char *) iov
[0].iov_base
) + ret
;
361 iov
[0].iov_len
-= ret
;
362 LTTNG_ASSERT(ret
<= len_last
);
364 } while ((ret
> 0 && ret
< len_last
) || (ret
< 0 && errno
== EINTR
));
367 if (errno
== EAGAIN
&& flags
& MSG_DONTWAIT
) {
369 * EAGAIN is expected in non-blocking mode and should
370 * not be reported as an error. Moreover, if no data
371 * was read, 0 must not be returned as it would be
372 * interpreted as an orderly shutdown of the socket.
376 PERROR("recvmsg inet");
377 } else if (ret
> 0) {
380 /* Else ret = 0 meaning an orderly shutdown. */
386 * Send buf data of size len. Using sendmsg API.
388 * Return the size of sent data.
390 ssize_t
lttcomm_sendmsg_inet_sock(struct lttcomm_sock
*sock
, const void *buf
, size_t len
, int flags
)
396 memset(&msg
, 0, sizeof(msg
));
398 iov
[0].iov_base
= (void *) buf
;
399 iov
[0].iov_len
= len
;
403 switch (sock
->proto
) {
404 case LTTCOMM_SOCK_UDP
:
406 struct sockaddr_in addr
= sock
->sockaddr
.addr
.sin
;
408 msg
.msg_name
= (struct sockaddr
*) &addr
;
409 msg
.msg_namelen
= sizeof(sock
->sockaddr
.addr
.sin
);
417 ret
= sendmsg(sock
->fd
, &msg
, flags
);
418 } while (ret
< 0 && errno
== EINTR
);
421 * Only warn about EPIPE when quiet mode is deactivated.
422 * We consider EPIPE as expected.
424 if (errno
!= EPIPE
|| !lttng_opt_quiet
) {
425 PERROR("sendmsg inet");
433 * Shutdown cleanly and close.
435 int lttcomm_close_inet_sock(struct lttcomm_sock
*sock
)
439 /* Don't try to close an invalid marked socket */
440 if (sock
->fd
== -1) {
444 ret
= close(sock
->fd
);
446 PERROR("close inet");
456 * Return value read from /proc or else 0 if value is not found.
458 static unsigned long read_proc_value(const char *path
)
463 unsigned long val
= 0;
466 fd
= open(path
, O_RDONLY
);
471 size_ret
= lttng_read(fd
, buf
, sizeof(buf
));
473 * Allow reading a file smaller than buf, but keep space for
476 if (size_ret
< 0 || size_ret
>= sizeof(buf
)) {
477 PERROR("read proc failed");
480 buf
[size_ret
] = '\0';
483 r_val
= strtol(buf
, nullptr, 10);
484 if (errno
!= 0 || r_val
< -1L) {
496 PERROR("close /proc value");
502 void lttcomm_inet_init()
504 unsigned long syn_retries
, fin_timeout
, syn_timeout
, env
;
506 env
= lttcomm_get_network_timeout();
508 lttcomm_inet_tcp_timeout
= env
;
512 /* Assign default value and see if we can change it. */
513 lttcomm_inet_tcp_timeout
= DEFAULT_INET_TCP_TIMEOUT
;
515 syn_retries
= read_proc_value(LTTCOMM_INET_PROC_SYN_RETRIES_PATH
);
516 fin_timeout
= read_proc_value(LTTCOMM_INET_PROC_FIN_TIMEOUT_PATH
);
518 syn_timeout
= syn_retries
* LTTCOMM_INET_SYN_TIMEOUT_FACTOR
;
521 * Get the maximum between the two possible timeout value and use that to
522 * get the maximum with the default timeout.
524 lttcomm_inet_tcp_timeout
=
525 std::max(std::max(syn_timeout
, fin_timeout
), lttcomm_inet_tcp_timeout
);
528 DBG("TCP inet operation timeout set to %lu sec", lttcomm_inet_tcp_timeout
);