Skip to content

Commit bbc6c66

Browse files
rluboscarlescufi
authored andcommitted
net: websocket: Fix poll handling for offloaded sockets
ZFD_IOCTL_POLL_OFFLOAD operation needed special handling, as it needed to modify the fds table for the offloaded implementation, overwriting websocket file descriptors with the underlying offloaded ones. This is only needed for the offloaded sockets, as the native implmentation use POLL_PREPARE/UPDATE operations instead. Signed-off-by: Robert Lubos <[email protected]>
1 parent a6a9d7a commit bbc6c66

File tree

1 file changed

+77
-12
lines changed

1 file changed

+77
-12
lines changed

subsys/net/lib/websocket/websocket.c

Lines changed: 77 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -434,23 +434,88 @@ static int websocket_close_vmeth(void *obj)
434434
return ret;
435435
}
436436

437+
static inline int websocket_poll_offload(struct zsock_pollfd *fds, int nfds,
438+
int timeout)
439+
{
440+
int fd_backup[CONFIG_NET_SOCKETS_POLL_MAX];
441+
const struct fd_op_vtable *vtable;
442+
void *ctx;
443+
int ret = 0;
444+
int i;
445+
446+
/* Overwrite websocket file decriptors with underlying ones. */
447+
for (i = 0; i < nfds; i++) {
448+
fd_backup[i] = fds[i].fd;
449+
450+
ctx = z_get_fd_obj(fds[i].fd,
451+
(const struct fd_op_vtable *)
452+
&websocket_fd_op_vtable,
453+
0);
454+
if (ctx == NULL) {
455+
continue;
456+
}
457+
458+
fds[i].fd = ((struct websocket_context *)ctx)->real_sock;
459+
}
460+
461+
/* Get offloaded sockets vtable. */
462+
ctx = z_get_fd_obj_and_vtable(fds[0].fd,
463+
(const struct fd_op_vtable **)&vtable,
464+
NULL);
465+
if (ctx == NULL) {
466+
errno = EINVAL;
467+
ret = -1;
468+
goto exit;
469+
}
470+
471+
ret = z_fdtable_call_ioctl(vtable, ctx, ZFD_IOCTL_POLL_OFFLOAD,
472+
fds, nfds, timeout);
473+
474+
exit:
475+
/* Restore original fds. */
476+
for (i = 0; i < nfds; i++) {
477+
fds[i].fd = fd_backup[i];
478+
}
479+
480+
return ret;
481+
}
482+
437483
static int websocket_ioctl_vmeth(void *obj, unsigned int request, va_list args)
438484
{
439485
struct websocket_context *ctx = obj;
440-
const struct fd_op_vtable *vtable;
441-
void *core_obj;
442-
443-
core_obj = z_get_fd_obj_and_vtable(
444-
ctx->real_sock,
445-
(const struct fd_op_vtable **)&vtable,
446-
NULL);
447-
if (core_obj == NULL) {
448-
errno = EBADF;
449-
return -1;
486+
487+
switch (request) {
488+
case ZFD_IOCTL_POLL_OFFLOAD: {
489+
struct zsock_pollfd *fds;
490+
int nfds;
491+
int timeout;
492+
493+
fds = va_arg(args, struct zsock_pollfd *);
494+
nfds = va_arg(args, int);
495+
timeout = va_arg(args, int);
496+
497+
return websocket_poll_offload(fds, nfds, timeout);
450498
}
451499

452-
/* Pass the call to the core socket implementation. */
453-
return vtable->ioctl(core_obj, request, args);
500+
default: {
501+
const struct fd_op_vtable *vtable;
502+
void *core_obj;
503+
504+
core_obj = z_get_fd_obj_and_vtable(
505+
ctx->real_sock,
506+
(const struct fd_op_vtable **)&vtable,
507+
NULL);
508+
if (core_obj == NULL) {
509+
errno = EBADF;
510+
return -1;
511+
}
512+
513+
/* Pass the call to the core socket implementation. */
514+
return vtable->ioctl(core_obj, request, args);
515+
}
516+
}
517+
518+
return 0;
454519
}
455520

456521
static int websocket_prepare_and_send(struct websocket_context *ctx,

0 commit comments

Comments
 (0)