217
return fd;
218
}
219
220
+static int parse_connection_definition(
221
+ char *definition,
222
+ char **host,
223
+ char **service,
224
+ char **iface,
225
+ int *protocol,
226
+ int *socktype,
227
+ char **unix_path)
228
+{
229
+ if(!definition || !*definition)
230
+ return -1;
231
+
232
+ *host = definition;
233
+ *service = NULL;
234
+ *iface = "";
235
+ *protocol = IPPROTO_TCP;
236
+ *socktype = SOCK_STREAM;
237
+ *unix_path = NULL;
238
+
239
+ if(strncmp(*host, "tcp:", 4) == 0) {
240
+ *host += 4;
241
+ *protocol = IPPROTO_TCP;
242
+ *socktype = SOCK_STREAM;
243
+ }
244
+ else if(strncmp(*host, "udp:", 4) == 0) {
245
+ *host += 4;
246
+ *protocol = IPPROTO_UDP;
247
+ *socktype = SOCK_DGRAM;
248
+ }
249
+ else if(strncmp(*host, "unix:", 5) == 0) {
250
+ *unix_path = *host + 5;
251
+ return 1;
252
+ }
253
+ else if(**host == '/') {
254
+ *unix_path = *host;
255
+ return 1;
256
+ }
257
+
258
+ char *e = *host;
259
+ if(*e == '[') {
260
+ e = ++(*host);
261
+ while(*e && *e != ']') e++;
262
+ if(*e == ']') {
263
+ *e = '\0';
264
+ e++;
265
+ }
266
+ }
267
+ else {
268
+ while(*e && *e != ':' && *e != '%') e++;
269
+ }
270
+
271
+ if(*e == '%') {
272
+ *e = '\0';
273
+ e++;
274
+ *iface = e;
275
+ while(*e && *e != ':') e++;
276
+ }
277
+
278
+ if(*e == ':') {
279
+ *e = '\0';
280
+ e++;
281
+ *service = e;
282
+ }
283
+
284
+ if(!**host)
285
+ return -1;
286
+
287
+ return 0;
288
+}
289
+
290
+bool connect_to_definition_get_service(const char *definition, int default_port, char *service, size_t service_size) {
291
+ if(!service || !service_size)
292
+ return false;
293
+
294
+ snprintfz(service, service_size, "%d", default_port);
295
+
296
+ if(!definition || !*definition)
297
+ return true;
298
+
299
+ const char *s = definition;
300
+ if(strncmp(s, "tcp:", 4) == 0 || strncmp(s, "udp:", 4) == 0)
301
+ s += 4;
302
+ else if(strncmp(s, "unix:", 5) == 0 || *s == '/')
303
+ return true;
304
+
305
+ const char *e = s;
306
+ size_t host_len = 0;
307
+ if(*e == '[') {
308
+ const char *host_start = ++e;
309
+ while(*e && *e != ']') e++;
310
+ host_len = (size_t)(e - host_start);
311
+ if(*e == ']')
312
+ e++;
313
+ }
314
+ else {
315
+ const char *host_start = e;
316
+ while(*e && *e != ':' && *e != '%') e++;
317
+ host_len = (size_t)(e - host_start);
318
+ }
319
+
320
+ if(!host_len)
321
+ return false;
322
+
323
+ if(*e == '%') {
324
+ e++;
325
+ while(*e && *e != ':') e++;
326
+ }
327
+
328
+ if(*e == ':' && *(e + 1))
329
+ snprintfz(service, service_size, "%s", e + 1);
330
+
331
+ return true;
332
+}
333
+
334
// connect_to_this()
335
//
336
// definition format:
357
char default_service[10 + 1];
358
snprintfz(default_service, 10, "%d", default_port);
359
246
- char *host = buffer, *service = default_service, *iface = "";
247
- int protocol = IPPROTO_TCP, socktype = SOCK_STREAM;
360
+ char *host = NULL, *service = NULL, *iface = NULL, *unix_path = NULL;
361
+ int protocol = 0, socktype = 0;
362
uint32_t scope_id = 0;
363
250
- if(strncmp(host, "tcp:", 4) == 0) {
251
- host += 4;
252
- protocol = IPPROTO_TCP;
253
- socktype = SOCK_STREAM;
254
- }
255
- else if(strncmp(host, "udp:", 4) == 0) {
256
- host += 4;
257
- protocol = IPPROTO_UDP;
258
- socktype = SOCK_DGRAM;
259
- }
260
- else if(strncmp(host, "unix:", 5) == 0) {
261
- char *path = host + 5;
262
- return connect_to_unix(path, timeout);
263
- }
264
- else if(*host == '/') {
265
- char *path = host;
266
- return connect_to_unix(path, timeout);
267
- }
268
-
269
- char *e = host;
270
- if(*e == '[') {
271
- e = ++host;
272
- while(*e && *e != ']') e++;
273
- if(*e == ']') {
274
- *e = '\0';
275
- e++;
276
- }
277
- }
278
- else {
279
- while(*e && *e != ':' && *e != '%') e++;
280
- }
281
-
282
- if(*e == '%') {
283
- *e = '\0';
284
- e++;
285
- iface = e;
286
- while(*e && *e != ':') e++;
287
- }
288
-
289
- if(*e == ':') {
290
- *e = '\0';
291
- e++;
292
- service = e;
293
- }
364
+ int rc = parse_connection_definition(
365
+ buffer, &host, &service, &iface, &protocol, &socktype, &unix_path);
366
+ if(rc == 1)
367
+ return connect_to_unix(unix_path, timeout);
368
295
- if(!*host) {
369
+ if(rc == -1) {
370
nd_log(NDLS_DAEMON, NDLP_ERR,
371
"Definition '%s' does not specify a host.",
372
definition);
374
return -ND_SOCK_ERR_NO_HOST_IN_DEFINITION;
375
}
376
303
- if(*iface) {
377
+ if(iface && *iface) {
378
scope_id = if_nametoindex(iface);
379
if(!scope_id)
380
nd_log(NDLS_DAEMON, NDLP_ERR,
307
- "Cannot find a network interface named '%s'. Continuing with limiting the network interface",
381
+ "Cannot find a network interface named '%s'. Continuing without limiting the network interface",
382
iface);
383
}
384
311
- if(!*service)
385
+ if(!service || !*service)
386
service = default_service;
387
388