Skip to content

Commit

Permalink
udpsrc: stores the index of the interface the packet was received on
Browse files Browse the repository at this point in the history
To enable this, the socket option IP_PKTINFO must be set first:

    int fd;
    ubase_assert(upipe_udpsrc_get_fd(upipe_udpsrc, &fd));
    const int yes = 1;
    if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &yes, sizeof(yes)) < 0) {
        perror("setsockopt");
        return 1;
    }
  • Loading branch information
funman committed Sep 13, 2024
1 parent 0654abc commit 8135de9
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
1 change: 1 addition & 0 deletions include/upipe/uref_block.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ extern "C" {
UREF_ATTR_VOID_UREF(block, start, UREF_FLAG_BLOCK_START, start of logical block)
UREF_ATTR_VOID_UREF(block, end, UREF_FLAG_BLOCK_END, end of logical block)
UREF_ATTR_UNSIGNED(block, header_size, "b.header", global headers size)
UREF_ATTR_UNSIGNED(block, net_ifindex, "b.ifindex", network interface index)

/** @This returns a new uref pointing to a new ubuf pointing to a block.
* This is equivalent to the two operations sequentially, and is a shortcut.
Expand Down
36 changes: 34 additions & 2 deletions lib/upipe-modules/upipe_udp_source.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@
#include <assert.h>
#include <sys/socket.h>

#include <netinet/in.h>

/** default size of buffers when unspecified */
#define UBUF_DEFAULT_SIZE 4096

Expand Down Expand Up @@ -205,10 +207,40 @@ static void upipe_udpsrc_worker(struct upump *upump)
struct sockaddr_storage addr;
socklen_t addrlen = sizeof(addr);

ssize_t ret = recvfrom(upipe_udpsrc->fd, buffer, upipe_udpsrc->output_size,
0, (struct sockaddr*)&addr, &addrlen);
int ifindex = -1;

uint8_t ancillary[CMSG_SPACE(sizeof(struct in_pktinfo))];
struct iovec iov[1] = {
{
.iov_base = buffer,
.iov_len = upipe_udpsrc->output_size,
}
};

struct msghdr msg = {
.msg_name = (struct sockaddr*)&addr,
.msg_namelen = addrlen,
.msg_iov = iov,
.msg_iovlen = 1,
.msg_control = ancillary,
.msg_controllen = sizeof(ancillary),
};

ssize_t ret = recvmsg(upipe_udpsrc->fd, &msg, 0);
addrlen = msg.msg_namelen;

for (struct cmsghdr *c = CMSG_FIRSTHDR(&msg); c; c = CMSG_NXTHDR(&msg, c)) {
if (c->cmsg_level == IPPROTO_IP && c->cmsg_type == IP_PKTINFO) {
struct in_pktinfo *info = (void*)CMSG_DATA(c);
ifindex = info->ipi_ifindex;
}
}

uref_block_unmap(uref, 0);

if (ifindex >= 0)
uref_block_set_net_ifindex(uref, ifindex);

if (unlikely(ret == -1)) {
uref_free(uref);
switch (errno) {
Expand Down

0 comments on commit 8135de9

Please sign in to comment.