Skip to content

Commit

Permalink
feat: add local address to sender
Browse files Browse the repository at this point in the history
Add possibility to choose a local address for unyte_sender. Set
IP_FREEBIND or IPV6_FREEBIND if available.
  • Loading branch information
jeremie6wind committed Sep 19, 2023
1 parent 0fd90ae commit d1559e3
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
64 changes: 64 additions & 0 deletions src/unyte_sender.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,64 @@
#include <string.h>
#include <net/if.h>
#include <netdb.h>
#include <errno.h>
#include "unyte_sender.h"

static void set_ipv4_freebind(int sockfd)
{
#ifdef IP_FREEBIND
int opt = 1;
if (setsockopt(sockfd, IPPROTO_IP, IP_FREEBIND, (void *)&opt, sizeof(opt)) == -1) {
printf("couldn't set IP_FREEBIND: %d %s\n", errno, strerror(errno));
}
#endif
}

static void set_ipv6_freebind(int sockfd)
{
#ifdef IPV6_FREEBIND
int opt = 1;
if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_FREEBIND, (void *)&opt, sizeof(opt)) == -1) {
printf("couldn't set IPV6_FREEBIND: %d %s\n", errno, strerror(errno));
}
#endif
}

static int set_local_address(int sockfd, const char *local_address)
{
struct addrinfo *local_addr_info = NULL;
struct addrinfo hints;

memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_DGRAM;
hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;

if (getaddrinfo(local_address, NULL, &hints, &local_addr_info)) {
printf("getaddrinfo error on: %s\n", local_address);
return -1;
}

if (local_addr_info->ai_family == AF_INET) {
set_ipv4_freebind(sockfd);
} else if (local_addr_info->ai_family == AF_INET6) {
set_ipv6_freebind(sockfd);
} else {
printf("%s is an unknown address format %d\n", local_address, local_addr_info->ai_family);
freeaddrinfo(local_addr_info);
return -1;
}

if (bind(sockfd, local_addr_info->ai_addr, local_addr_info->ai_addrlen)) {
perror("bind socket error");
freeaddrinfo(local_addr_info);
return -1;
}

freeaddrinfo(local_addr_info);
return 0;
}

struct unyte_sender_socket *unyte_start_sender(unyte_sender_options_t *options)
{
struct addrinfo *addr_info;
Expand Down Expand Up @@ -66,6 +122,14 @@ struct unyte_sender_socket *unyte_start_sender(unyte_sender_options_t *options)
}
}

const char *local_address = options->local_address;
if (local_address && strlen(local_address) > 0) {
if (set_local_address(sockfd, local_address)) {
perror("Bind socket to address failed");
exit(EXIT_FAILURE);
}
}

uint64_t send_buf_size = DEFAULT_SK_SND_BUFF_SIZE;
if (options->socket_buff_size > 0)
send_buf_size = options->socket_buff_size;
Expand Down
1 change: 1 addition & 0 deletions src/unyte_sender.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ typedef struct
char *port;
uint default_mtu;
char *interface;
char *local_address;
uint64_t socket_buff_size; // socket buffer size in bytes
} unyte_sender_options_t;

Expand Down

0 comments on commit d1559e3

Please sign in to comment.