1#define _POSIX_C_SOURCE 200809L
16#include <netinet/in.h>
19#include <sys/socket.h>
22static rte_status_t posix_socket_set_nonblocking(rte_os_socket_handle_t handle,
bool nonblocking);
25static rte_status_t posix_socket_open(rte_os_socket_type_t type, rte_os_socket_handle_t *out_handle)
32 if (out_handle == NULL)
34 return RTE_STATUS_INVALID_PARAM;
37 if (type == RTE_OS_SOCKET_TYPE_UDP)
39 sock_type = SOCK_DGRAM;
41 else if (type == RTE_OS_SOCKET_TYPE_TCP)
43 sock_type = SOCK_STREAM;
47 return RTE_STATUS_NOT_SUPPORTED;
50 fd = socket(domain, sock_type, 0);
53 return RTE_STATUS_INTERNAL_ERROR;
56 (void)setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, (socklen_t)
sizeof(reuse));
58 (void)setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &reuse, (socklen_t)
sizeof(reuse));
63 if (posix_socket_set_nonblocking((rte_os_socket_handle_t)fd,
true) != RTE_STATUS_OK)
66 return RTE_STATUS_INTERNAL_ERROR;
69 *out_handle = (rte_os_socket_handle_t)fd;
73static rte_status_t posix_socket_bind(rte_os_socket_handle_t handle,
const char *host, uint16_t port)
76 struct sockaddr_in addr;
80 return RTE_STATUS_INVALID_PARAM;
83 memset(&addr, 0,
sizeof(addr));
84 addr.sin_family = AF_INET;
85 addr.sin_port = htons(port);
87 if ((host == NULL) || (host[0] ==
'\0'))
89 addr.sin_addr.s_addr = INADDR_ANY;
93 if (inet_pton(AF_INET, host, &addr.sin_addr) != 1)
95 return RTE_STATUS_INVALID_PARAM;
99 if (bind(fd, (
const struct sockaddr *)(
const void *)&addr, (socklen_t)
sizeof(addr)) != 0)
101 return RTE_STATUS_INTERNAL_ERROR;
104 return RTE_STATUS_OK;
107static rte_status_t posix_socket_connect(rte_os_socket_handle_t handle,
const char *host, uint16_t port)
109 int fd = (int)handle;
110 struct sockaddr_in addr;
112 if ((fd < 0) || (host == NULL))
114 return RTE_STATUS_INVALID_PARAM;
117 memset(&addr, 0,
sizeof(addr));
118 addr.sin_family = AF_INET;
119 addr.sin_port = htons(port);
121 if (inet_pton(AF_INET, host, &addr.sin_addr) != 1)
123 return RTE_STATUS_INVALID_PARAM;
126 if (connect(fd, (
const struct sockaddr *)(
const void *)&addr, (socklen_t)
sizeof(addr)) != 0)
128 if (errno == EINPROGRESS)
130 return RTE_STATUS_OK;
132 return RTE_STATUS_INTERNAL_ERROR;
135 return RTE_STATUS_OK;
138static rte_status_t posix_socket_send(rte_os_socket_handle_t handle,
const void *buf,
139 size_t len,
size_t *out_sent)
141 int fd = (int)handle;
144 if ((fd < 0) || (buf == NULL))
146 return RTE_STATUS_INVALID_PARAM;
149 rc = send(fd, buf, len, 0);
152 if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
154 return RTE_STATUS_TIMEOUT;
156 return RTE_STATUS_INTERNAL_ERROR;
159 if (out_sent != NULL)
161 *out_sent = (size_t)rc;
163 return RTE_STATUS_OK;
166static rte_status_t posix_socket_sendto(rte_os_socket_handle_t handle,
const void *buf,
167 size_t len,
const char *host, uint16_t port,
170 int fd = (int)handle;
171 struct sockaddr_in addr;
174 if ((fd < 0) || (buf == NULL) || (host == NULL))
176 return RTE_STATUS_INVALID_PARAM;
179 memset(&addr, 0,
sizeof(addr));
180 addr.sin_family = AF_INET;
181 addr.sin_port = htons(port);
183 if (inet_pton(AF_INET, host, &addr.sin_addr) != 1)
185 return RTE_STATUS_INVALID_PARAM;
188 rc = sendto(fd, buf, len, 0, (
const struct sockaddr *)(
const void *)&addr, (socklen_t)
sizeof(addr));
191 if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
193 return RTE_STATUS_TIMEOUT;
195 return RTE_STATUS_INTERNAL_ERROR;
198 if (out_sent != NULL)
200 *out_sent = (size_t)rc;
202 return RTE_STATUS_OK;
205static rte_status_t posix_socket_recv(rte_os_socket_handle_t handle,
void *buf,
206 size_t len,
size_t *out_recv)
208 int fd = (int)handle;
211 if ((fd < 0) || (buf == NULL) || (out_recv == NULL))
213 return RTE_STATUS_INVALID_PARAM;
216 rc = recv(fd, buf, len, 0);
219 if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
221 return RTE_STATUS_TIMEOUT;
223 return RTE_STATUS_INTERNAL_ERROR;
226 *out_recv = (size_t)rc;
227 return RTE_STATUS_OK;
230static rte_status_t posix_socket_recvfrom(rte_os_socket_handle_t handle,
void *buf,
231 size_t len,
char *out_host,
size_t host_len,
232 uint16_t *out_port,
size_t *out_recv)
234 int fd = (int)handle;
235 struct sockaddr_in addr;
236 socklen_t addr_len = (socklen_t)
sizeof(addr);
239 if ((fd < 0) || (buf == NULL) || (out_recv == NULL))
241 return RTE_STATUS_INVALID_PARAM;
244 memset(&addr, 0,
sizeof(addr));
245 rc = recvfrom(fd, buf, len, 0, (
struct sockaddr *)(
void *)&addr, &addr_len);
248 if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
250 return RTE_STATUS_TIMEOUT;
252 return RTE_STATUS_INTERNAL_ERROR;
255 if (out_host != NULL && host_len > 0U)
257 (void)inet_ntop(AF_INET, &addr.sin_addr, out_host, (socklen_t)host_len);
259 if (out_port != NULL)
261 *out_port = ntohs(addr.sin_port);
264 *out_recv = (size_t)rc;
265 return RTE_STATUS_OK;
268static rte_status_t posix_socket_poll(rte_os_socket_handle_t handle, uint32_t events,
269 rte_duration_ms_t timeout_ms, uint32_t *out_revents)
271 int fd = (int)handle;
275 if ((fd < 0) || (out_revents == NULL))
277 return RTE_STATUS_INVALID_PARAM;
280 memset(&pfd, 0,
sizeof(pfd));
282 if ((events & RTE_OS_SOCKET_EVENT_READ) != 0U)
284 pfd.events |= POLLIN;
286 if ((events & RTE_OS_SOCKET_EVENT_WRITE) != 0U)
288 pfd.events |= POLLOUT;
291 rc = poll(&pfd, 1, posix_poll_timeout_ms(timeout_ms));
296 return RTE_STATUS_TIMEOUT;
298 return RTE_STATUS_INTERNAL_ERROR;
303 return RTE_STATUS_TIMEOUT;
307 if ((pfd.revents & POLLIN) != 0)
309 *out_revents |= RTE_OS_SOCKET_EVENT_READ;
311 if ((pfd.revents & POLLOUT) != 0)
313 *out_revents |= RTE_OS_SOCKET_EVENT_WRITE;
315 if ((pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) != 0)
317 *out_revents |= RTE_OS_SOCKET_EVENT_ERROR;
320 return RTE_STATUS_OK;
323static rte_status_t posix_socket_set_nonblocking(rte_os_socket_handle_t handle,
bool nonblocking)
325 int fd = (int)handle;
330 return RTE_STATUS_INVALID_PARAM;
333 flags = fcntl(fd, F_GETFL, 0);
336 return RTE_STATUS_INTERNAL_ERROR;
339 flags = nonblocking ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK);
340 if (fcntl(fd, F_SETFL, flags) < 0)
342 return RTE_STATUS_INTERNAL_ERROR;
345 return RTE_STATUS_OK;
348static rte_status_t posix_socket_close(rte_os_socket_handle_t handle)
350 int fd = (int)handle;
355 return RTE_STATUS_OK;
358static const rte_os_socket_ops_t s_posix_socket_ops = {
361 posix_socket_connect,
365 posix_socket_recvfrom,
367 posix_socket_set_nonblocking,
373 return &s_posix_socket_ops;
Real POSIX/Linux OSAdapter for every OAL service (ADR-018).
const rte_os_socket_ops_t * rte_posix_osadapter_socket_ops(void)
The POSIX raw OS socket operations vtable (UDP and TCP).
Private helpers: millisecond waits for poll()'s int timeout argument.