Skip to content

Commit d1559e3

Browse files
committed
feat: add local address to sender
Add possibility to choose a local address for unyte_sender. Set IP_FREEBIND or IPV6_FREEBIND if available.
1 parent 0fd90ae commit d1559e3

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

src/unyte_sender.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,64 @@
77
#include <string.h>
88
#include <net/if.h>
99
#include <netdb.h>
10+
#include <errno.h>
1011
#include "unyte_sender.h"
1112

13+
static void set_ipv4_freebind(int sockfd)
14+
{
15+
#ifdef IP_FREEBIND
16+
int opt = 1;
17+
if (setsockopt(sockfd, IPPROTO_IP, IP_FREEBIND, (void *)&opt, sizeof(opt)) == -1) {
18+
printf("couldn't set IP_FREEBIND: %d %s\n", errno, strerror(errno));
19+
}
20+
#endif
21+
}
22+
23+
static void set_ipv6_freebind(int sockfd)
24+
{
25+
#ifdef IPV6_FREEBIND
26+
int opt = 1;
27+
if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_FREEBIND, (void *)&opt, sizeof(opt)) == -1) {
28+
printf("couldn't set IPV6_FREEBIND: %d %s\n", errno, strerror(errno));
29+
}
30+
#endif
31+
}
32+
33+
static int set_local_address(int sockfd, const char *local_address)
34+
{
35+
struct addrinfo *local_addr_info = NULL;
36+
struct addrinfo hints;
37+
38+
memset(&hints, 0, sizeof(hints));
39+
hints.ai_socktype = SOCK_DGRAM;
40+
hints.ai_family = AF_UNSPEC;
41+
hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;
42+
43+
if (getaddrinfo(local_address, NULL, &hints, &local_addr_info)) {
44+
printf("getaddrinfo error on: %s\n", local_address);
45+
return -1;
46+
}
47+
48+
if (local_addr_info->ai_family == AF_INET) {
49+
set_ipv4_freebind(sockfd);
50+
} else if (local_addr_info->ai_family == AF_INET6) {
51+
set_ipv6_freebind(sockfd);
52+
} else {
53+
printf("%s is an unknown address format %d\n", local_address, local_addr_info->ai_family);
54+
freeaddrinfo(local_addr_info);
55+
return -1;
56+
}
57+
58+
if (bind(sockfd, local_addr_info->ai_addr, local_addr_info->ai_addrlen)) {
59+
perror("bind socket error");
60+
freeaddrinfo(local_addr_info);
61+
return -1;
62+
}
63+
64+
freeaddrinfo(local_addr_info);
65+
return 0;
66+
}
67+
1268
struct unyte_sender_socket *unyte_start_sender(unyte_sender_options_t *options)
1369
{
1470
struct addrinfo *addr_info;
@@ -66,6 +122,14 @@ struct unyte_sender_socket *unyte_start_sender(unyte_sender_options_t *options)
66122
}
67123
}
68124

125+
const char *local_address = options->local_address;
126+
if (local_address && strlen(local_address) > 0) {
127+
if (set_local_address(sockfd, local_address)) {
128+
perror("Bind socket to address failed");
129+
exit(EXIT_FAILURE);
130+
}
131+
}
132+
69133
uint64_t send_buf_size = DEFAULT_SK_SND_BUFF_SIZE;
70134
if (options->socket_buff_size > 0)
71135
send_buf_size = options->socket_buff_size;

src/unyte_sender.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ typedef struct
1313
char *port;
1414
uint default_mtu;
1515
char *interface;
16+
char *local_address;
1617
uint64_t socket_buff_size; // socket buffer size in bytes
1718
} unyte_sender_options_t;
1819

0 commit comments

Comments
 (0)