blob: 2385a6992769e3bc26a32738e27680d10a7b6663 [file] [log] [blame]
James Kuszmaul82f6c042021-01-17 11:30:16 -08001/**
2 * @file sockopt.c Networking socket options
3 *
4 * Copyright (C) 2010 Creytiv.com
5 */
6#ifdef HAVE_UNISTD_H
7#include <unistd.h>
8#endif
9#include <fcntl.h>
10#include <re_types.h>
11#include <re_fmt.h>
12#include <re_net.h>
13
14
15#define DEBUG_MODULE "sockopt"
16#define DEBUG_LEVEL 5
17#include <re_dbg.h>
18
19
20/** Platform independent buffer type cast */
21#ifdef WIN32
22#define BUF_CAST (char *)
23#else
24#define BUF_CAST
25#endif
26
27
28/**
29 * Set socket option blocking or non-blocking
30 *
31 * @param fd Socket file descriptor
32 * @param blocking true for blocking, false for non-blocking
33 *
34 * @return 0 if success, otherwise errorcode
35 */
36int net_sockopt_blocking_set(int fd, bool blocking)
37{
38#ifdef WIN32
39 unsigned long noblock = !blocking;
40 int err = 0;
41
42 if (0 != ioctlsocket(fd, FIONBIO, &noblock)) {
43 err = WSAGetLastError();
44 DEBUG_WARNING("nonblock set: fd=%d err=%d (%m)\n",
45 fd, err, err);
46 }
47 return err;
48#else
49 int flags;
50 int err = 0;
51
52 flags = fcntl(fd, F_GETFL);
53 if (-1 == flags) {
54 err = errno;
55 DEBUG_WARNING("sockopt set: fnctl F_GETFL: (%m)\n", err);
56 goto out;
57 }
58
59 if (blocking)
60 flags &= ~O_NONBLOCK;
61 else
62 flags |= O_NONBLOCK;
63
64 if (-1 == fcntl(fd, F_SETFL, flags)) {
65 err = errno;
66 DEBUG_WARNING("sockopt set: fcntl F_SETFL non-block (%m)\n",
67 err);
68 }
69
70 out:
71 return err;
72#endif
73}
74
75
76/**
77 * Set socket option to reuse address and port
78 *
79 * @param fd Socket file descriptor
80 * @param reuse true for reuse, false for no reuse
81 *
82 * @return 0 if success, otherwise errorcode
83 */
84int net_sockopt_reuse_set(int fd, bool reuse)
85{
86 int r = reuse;
87
88#ifdef SO_REUSEADDR
89 if (-1 == setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
90 BUF_CAST &r, sizeof(r))) {
91 DEBUG_WARNING("SO_REUSEADDR: %m\n", errno);
92 return errno;
93 }
94#endif
95
96#ifdef SO_REUSEPORT
97 if (-1 == setsockopt(fd, SOL_SOCKET, SO_REUSEPORT,
98 BUF_CAST &r, sizeof(r))) {
99 DEBUG_INFO("SO_REUSEPORT: %m\n", errno);
100 return errno;
101 }
102#endif
103
104#if !defined(SO_REUSEADDR) && !defined(SO_REUSEPORT)
105 (void)r;
106 (void)fd;
107 (void)reuse;
108 return ENOSYS;
109#else
110 return 0;
111#endif
112}