From 53d31eb26e2f022da19e2f69ae391d150dced4cf Mon Sep 17 00:00:00 2001 From: Ghislain Bourgeois Date: Mon, 9 Sep 2024 18:14:53 -0400 Subject: [PATCH] Use getaddrinfo() when connecting to rfsimulator This commits uses getaddrinfo(3) when connecting as client to the rfsimulator. This enables name lookups, through DNS or a hosts file. This change makes it easier to use the simulator in a dynamic environment like Docker or Kubernetes by only targeting the name of the container or service. --- radio/rfsimulator/simulator.c | 60 ++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/radio/rfsimulator/simulator.c b/radio/rfsimulator/simulator.c index c5197eaab8..776bbf73cc 100644 --- a/radio/rfsimulator/simulator.c +++ b/radio/rfsimulator/simulator.c @@ -29,6 +29,7 @@ */ #include +#include #include #include #include @@ -38,6 +39,8 @@ #include #include #include +#include + #include #include #include @@ -577,27 +580,62 @@ static int startServer(openair0_device *device) { return 0; } -static int startClient(openair0_device *device) { +static int client_try_connect(const char *host, uint16_t port) +{ + int sock = -1; + int s; + struct addrinfo *result = NULL; + struct addrinfo *rp = NULL; + + char dport[6]; + snprintf(dport, sizeof(dport), "%d", port); + + struct addrinfo hints = { + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM, + }; + + s = getaddrinfo(host, dport, &hints, &result); + if (s != 0) { + LOG_I(HW, "getaddrinfo: %s\n", gai_strerror(s)); + return -1; + } + for (rp = result; rp != NULL; rp = rp->ai_next) { + sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (sock == -1) { + continue; + } + + if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) { + LOG_I(HW, "Connection to %s:%d established\n", host, port); + break; + } + + close(sock); + } + + freeaddrinfo(result); + + return sock; +} + +static int startClient(openair0_device *device) +{ rfsimulator_state_t *t = device->priv; t->role = SIMU_ROLE_CLIENT; int sock; - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - LOG_E(HW, "socket(SOCK_STREAM) failed, errno(%d)\n", errno); - return -1; - } - struct sockaddr_in addr = {.sin_family = AF_INET, .sin_port = htons(t->port), .sin_addr = {.s_addr = INADDR_ANY}}; - addr.sin_addr.s_addr = inet_addr(t->ip); - bool connected=false; - while(!connected) { + while (true) { LOG_I(HW, "Trying to connect to %s:%d\n", t->ip, t->port); + sock = client_try_connect(t->ip, t->port); - if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { + if (sock > 0) { LOG_I(HW, "Connection to %s:%d established\n", t->ip, t->port); - connected=true; + break; } LOG_I(HW, "connect() to %s:%d failed, errno(%d)\n", t->ip, t->port, errno); + fprintf(stderr, "Could not connect\n"); sleep(1); }