Skip to content

Commit acb00cf

Browse files
Resolve network name for socket output
When the address provided in the configuration is not an IPV4 address (such as w.x.y.z) we now try to resolve the network name before connecting. This will allow using the socket output in environments where IP addresses are dynamically provided and not known when configuring the sensor (e.g. docker compose or k8s).
1 parent 4ee9e7f commit acb00cf

File tree

1 file changed

+72
-11
lines changed

1 file changed

+72
-11
lines changed

src/storage_socket.c

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,30 +90,91 @@ socket_connection(struct socket_context *ctx)
9090
return -1;
9191
}
9292

93+
/* Attemp to resolve network name from config.address and connect. */
9394
static int
94-
socket_initialize(struct storage_module *module)
95+
socket_resolve_and_connect(struct socket_context *ctx)
9596
{
96-
struct socket_context *ctx = module->context;
97-
98-
if (module->is_initialized)
99-
return -1;
100-
101-
if(addr_init(ctx->config, &(ctx->address)) == 0){
102-
zsys_error("socket: failed to parse uri: %s", ctx->config.address);
97+
struct addrinfo *result, *rp;
98+
struct addrinfo hints;
99+
int s;
100+
char portstr[8];
101+
bool is_connected = false;
102+
103+
memset(&hints, 0, sizeof(hints));
104+
hints.ai_family = AF_INET; /* IPv4 */
105+
hints.ai_socktype = SOCK_STREAM;
106+
hints.ai_flags = 0;
107+
hints.ai_protocol = 0;
108+
hints.ai_canonname = NULL;
109+
hints.ai_addr = NULL;
110+
hints.ai_next = NULL;
111+
112+
bson_snprintf (portstr, sizeof portstr, "%hu", ctx->config.port);
113+
114+
s = getaddrinfo(ctx->config.address, portstr, &hints, &result);
115+
if (s!= 0) {
116+
zsys_error("unable to get addr info from %s", ctx->config.address);
103117
goto error;
104118
}
105119

120+
zsys_debug("Name %s resolved, attempt connecting", ctx->config.address);
106121
ctx->socket = socket(PF_INET, SOCK_STREAM, 0);
107122
if(ctx->socket == -1) {
108123
zsys_error("socket: failed create socket");
109124
goto error;
110125
}
111-
112-
if(socket_connection(ctx) == -1){
113-
zsys_error("socket: unable to connect to %s", ctx->config.address);
126+
// attemps to connect to the first possible result from getaddrinfo
127+
for (rp = result; rp; rp = rp->ai_next) {
128+
memcpy(&ctx->address, rp->ai_addr, rp->ai_addrlen);
129+
if(socket_connection(ctx) == -1){
130+
zsys_warning("socket: unable to connect to %s", ctx->config.address);
131+
} else {
132+
zsys_info("Connected !!");
133+
is_connected = true;
134+
break;
135+
}
136+
}
137+
freeaddrinfo (result);
138+
if (! is_connected) {
139+
zsys_error("Could not connect to any resolved address for %s", ctx->config.address);
114140
goto error;
115141
}
116142

143+
return 0;
144+
145+
error:
146+
return -1;
147+
}
148+
149+
static int
150+
socket_initialize(struct storage_module *module)
151+
{
152+
struct socket_context *ctx = module->context;
153+
154+
if (module->is_initialized)
155+
return -1;
156+
157+
if(addr_init(ctx->config, &(ctx->address)) == 1){
158+
// ctx.address is a valid IP address, attempt connecting:
159+
ctx->socket = socket(PF_INET, SOCK_STREAM, 0);
160+
if(ctx->socket == -1) {
161+
zsys_error("socket: failed create socket");
162+
goto error;
163+
}
164+
if(socket_connection(ctx) == -1){
165+
zsys_error("socket: unable to connect to %s", ctx->config.address);
166+
goto error;
167+
}
168+
169+
} else {
170+
171+
zsys_info("socket: failed to parse uri: %s, trying to resolve name", ctx->config.address);
172+
if (socket_resolve_and_connect(ctx) == -1) {
173+
zsys_error("Could not resolve and connect to %s", ctx->config.address);
174+
goto error;
175+
}
176+
}
177+
117178
module->is_initialized = true;
118179
return 0;
119180

0 commit comments

Comments
 (0)