Skip to content

Commit

Permalink
udp: add optional send/recv handler (#602)
Browse files Browse the repository at this point in the history
  • Loading branch information
alfredh authored Dec 8, 2022
1 parent ee1e0b0 commit 6c7f92a
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 0 deletions.
9 changes: 9 additions & 0 deletions include/re_udp.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
struct sa;
struct udp_sock;

typedef int (udp_send_h)(const struct sa *dst,
struct mbuf *mb, void *arg);

/**
* Defines the UDP Receive handler
Expand All @@ -22,6 +24,10 @@ typedef void (udp_error_h)(int err, void *arg);

int udp_listen(struct udp_sock **usp, const struct sa *local,
udp_recv_h *rh, void *arg);
int udp_alloc_sockless(struct udp_sock **usp,
udp_send_h *sendh, udp_recv_h *recvh, void *arg);
int udp_alloc_fd(struct udp_sock **usp, re_sock_t fd,
udp_recv_h *recvh, void *arg);
int udp_connect(struct udp_sock *us, const struct sa *peer);
int udp_open(struct udp_sock **usp, int af);
int udp_send(struct udp_sock *us, const struct sa *dst, struct mbuf *mb);
Expand All @@ -35,11 +41,14 @@ void udp_handler_set(struct udp_sock *us, udp_recv_h *rh, void *arg);
void udp_error_handler_set(struct udp_sock *us, udp_error_h *eh);
int udp_thread_attach(struct udp_sock *us);
void udp_thread_detach(struct udp_sock *us);
re_sock_t udp_sock_fd(const struct udp_sock *us, int af);

int udp_multicast_join(struct udp_sock *us, const struct sa *group);
int udp_multicast_leave(struct udp_sock *us, const struct sa *group);
int udp_settos(struct udp_sock *us, uint8_t tos);
void udp_flush(const struct udp_sock *us);
void udp_recv_packet(struct udp_sock *us, const struct sa *src,
struct mbuf *mb);


/* Helper API */
Expand Down
105 changes: 105 additions & 0 deletions src/udp/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ enum {
/** Defines a UDP socket */
struct udp_sock {
struct list helpers; /**< List of UDP Helpers */
udp_send_h *sendh;
udp_recv_h *rh; /**< Receive handler */
udp_error_h *eh; /**< Error handler */
void *arg; /**< Handler argument */
Expand Down Expand Up @@ -373,6 +374,55 @@ int udp_listen(struct udp_sock **usp, const struct sa *local,
}


int udp_alloc_sockless(struct udp_sock **usp,
udp_send_h *sendh, udp_recv_h *recvh, void *arg)
{
if (!usp || !sendh)
return EINVAL;

struct udp_sock *us = mem_zalloc(sizeof(*us), udp_destructor);
if (!us)
return ENOMEM;

list_init(&us->helpers);

us->fd = RE_BAD_SOCK;
us->fd6 = RE_BAD_SOCK;
us->sendh = sendh;
us->rh = recvh ? recvh : dummy_udp_recv_handler;
us->arg = arg;
us->rxsz = UDP_RXSZ_DEFAULT;

*usp = us;

return 0;
}


int udp_alloc_fd(struct udp_sock **usp, re_sock_t fd,
udp_recv_h *recvh, void *arg)
{
if (!usp || fd==RE_BAD_SOCK)
return EINVAL;

struct udp_sock *us = mem_zalloc(sizeof(*us), udp_destructor);
if (!us)
return ENOMEM;

list_init(&us->helpers);

us->fd = fd;
us->fd6 = RE_BAD_SOCK;
us->rh = recvh ? recvh : dummy_udp_recv_handler;
us->arg = arg;
us->rxsz = UDP_RXSZ_DEFAULT;

*usp = us;

return 0;
}


/**
* Create an UDP socket with specified address family.
*
Expand Down Expand Up @@ -477,6 +527,10 @@ static int udp_send_internal(struct udp_sock *us, const struct sa *dst,
return err;
}

/* external send handler */
if (us->sendh)
return us->sendh(dst, mb, us->arg);

/* Connected socket? */
if (us->conn) {
if (send(fd, BUF_CAST mb->buf + mb->pos,
Expand Down Expand Up @@ -710,6 +764,28 @@ void udp_error_handler_set(struct udp_sock *us, udp_error_h *eh)
}


/**
* Get the File Descriptor from a UDP Socket
*
* @param us UDP Socket
* @param af Address Family
*
* @return File Descriptor, or RE_BAD_SOCK for errors
*/
re_sock_t udp_sock_fd(const struct udp_sock *us, int af)
{
if (!us)
return RE_BAD_SOCK;

switch (af) {

default:
case AF_INET: return us->fd;
case AF_INET6: return (us->fd6 != RE_BAD_SOCK) ? us->fd6 : us->fd;
}
}


/**
* Attach the current thread to the UDP Socket
*
Expand Down Expand Up @@ -925,3 +1001,32 @@ void udp_flush(const struct udp_sock *us)
;
}
}


void udp_recv_packet(struct udp_sock *us, const struct sa *src,
struct mbuf *mb)
{
struct sa hsrc;

if (!us || !src || !mb)
return;

struct le *le = us->helpers.head;
while (le) {
struct udp_helper *uh = le->data;
bool hdld;

le = le->next;

if (src != &hsrc) {
sa_cpy(&hsrc, src);
src = &hsrc;
}

hdld = uh->recvh(&hsrc, mb, uh->arg);
if (hdld)
return;
}

us->rh(src, mb, us->arg);
}

0 comments on commit 6c7f92a

Please sign in to comment.