10 #include <sys/socket.h>
11 #include <sys/types.h>
12 #include <netinet/tcp.h>
14 #include <net/gen/in.h>
15 #include <net/gen/tcp.h>
16 #include <net/gen/tcp_io.h>
17 #include <net/gen/udp.h>
18 #include <net/gen/udp_io.h>
22 static int _tcp_setsockopt(int sock
, int level
, int option_name
,
23 const void *option_value
, socklen_t option_len
);
25 static int _udp_setsockopt(int sock
, int level
, int option_name
,
26 const void *option_value
, socklen_t option_len
);
28 static int _uds_setsockopt(int sock
, int level
, int option_name
,
29 const void *option_value
, socklen_t option_len
);
35 __setsockopt(int fd
, int level
, int option_name
, const void * option_value
,
40 memset(&m
, 0, sizeof(m
));
41 m
.m_lc_vfs_sockopt
.fd
= fd
;
42 m
.m_lc_vfs_sockopt
.level
= level
;
43 m
.m_lc_vfs_sockopt
.name
= option_name
;
44 m
.m_lc_vfs_sockopt
.buf
= (vir_bytes
)option_value
;
45 m
.m_lc_vfs_sockopt
.len
= option_len
;
47 return _syscall(VFS_PROC_NR
, VFS_SETSOCKOPT
, &m
);
50 int setsockopt(int sock
, int level
, int option_name
,
51 const void *option_value
, socklen_t option_len
)
56 struct sockaddr_un uds_addr
;
58 r
= __setsockopt(sock
, level
, option_name
, option_value
, option_len
);
59 if (r
!= -1 || (errno
!= ENOTSOCK
&& errno
!= ENOSYS
))
62 r
= ioctl(sock
, NWIOGTCPOPT
, &tcpopt
);
63 if (r
!= -1 || errno
!= ENOTTY
)
67 /* Bad file descriptor */
70 return _tcp_setsockopt(sock
, level
, option_name
,
71 option_value
, option_len
);
74 r
= ioctl(sock
, NWIOGUDPOPT
, &udpopt
);
75 if (r
!= -1 || errno
!= ENOTTY
)
79 /* Bad file descriptor */
82 return _udp_setsockopt(sock
, level
, option_name
,
83 option_value
, option_len
);
86 r
= ioctl(sock
, NWIOGUDSADDR
, &uds_addr
);
87 if (r
!= -1 || errno
!= ENOTTY
)
91 /* Bad file descriptor */
94 return _uds_setsockopt(sock
, level
, option_name
,
95 option_value
, option_len
);
102 static int _tcp_setsockopt(int sock
, int level
, int option_name
,
103 const void *option_value
, socklen_t option_len
)
107 if (level
== SOL_SOCKET
&& option_name
== SO_REUSEADDR
)
109 if (option_len
!= sizeof(i
))
114 i
= *(const int *)option_value
;
117 /* At the moment there is no way to turn off
125 if (level
== SOL_SOCKET
&& option_name
== SO_KEEPALIVE
)
127 if (option_len
!= sizeof(i
))
132 i
= *(const int *)option_value
;
135 /* At the moment there is no way to turn off
143 if (level
== SOL_SOCKET
&& option_name
== SO_RCVBUF
)
145 if (option_len
!= sizeof(i
))
150 i
= *(const int *)option_value
;
153 /* The receive buffer is limited to 32K at the moment.
158 /* There is no way to reduce the receive buffer, do we have to
159 * let this call fail for smaller buffers?
163 if (level
== SOL_SOCKET
&& option_name
== SO_SNDBUF
)
165 if (option_len
!= sizeof(i
))
170 i
= *(const int *)option_value
;
173 /* The send buffer is limited to 32K at the moment.
178 /* There is no way to reduce the send buffer, do we have to
179 * let this call fail for smaller buffers?
183 if (level
== IPPROTO_TCP
&& option_name
== TCP_NODELAY
)
185 if (option_len
!= sizeof(i
))
190 i
= *(const int *)option_value
;
193 /* At the moment there is no way to turn on
202 fprintf(stderr
, "_tcp_setsocketopt: level %d, name %d\n",
210 static int _udp_setsockopt(int sock
, int level
, int option_name
,
211 const void *option_value
, socklen_t option_len
)
214 fprintf(stderr
, "_udp_setsocketopt: level %d, name %d\n",
223 static int _uds_setsockopt(int sock
, int level
, int option_name
,
224 const void *option_value
, socklen_t option_len
)
229 if (level
== SOL_SOCKET
&& option_name
== SO_RCVBUF
)
231 if (option_len
!= sizeof(size
))
236 size
= *(const size_t *)option_value
;
237 return ioctl(sock
, NWIOSUDSRCVBUF
, &size
);
240 if (level
== SOL_SOCKET
&& option_name
== SO_SNDBUF
)
242 if (option_len
!= sizeof(size
))
247 size
= *(const size_t *)option_value
;
248 return ioctl(sock
, NWIOSUDSSNDBUF
, &size
);
251 if (level
== SOL_SOCKET
&& option_name
== SO_REUSEADDR
)
253 if (option_len
!= sizeof(i
))
258 i
= *(const int *)option_value
;
261 /* At the moment there is no way to turn off
271 if (level
== SOL_SOCKET
&& option_name
== SO_PASSCRED
)
273 if (option_len
!= sizeof(i
))
278 i
= *(const int *)option_value
;
281 /* credentials can always be received. */
290 fprintf(stderr
, "_uds_setsocketopt: level %d, name %d\n",