MCPcopy Index your code
hub / github.com/RsyncProject/rsync / open_socket_in

Function open_socket_in

socket.c:402–500  ·  view source on GitHub ↗

Open one or more sockets for incoming data using the specified type, * port, and address. * * The getaddrinfo() call may return several address results, e.g. for * the machine's IPv4 and IPv6 name. * * We return an array of file-descriptors to the sockets, with a trailing * -1 value to indicate the end of the list. * * bind_addr: local address to bind, or NULL to allow it to default. */

Source from the content-addressed store, hash-verified

400 *
401 * bind_addr: local address to bind, or NULL to allow it to default. */
402static int *open_socket_in(int type, int port, const char *bind_addr,
403 int af_hint)
404{
405 int one = 1;
406 int s, *socks, maxs, i, ecnt;
407 struct addrinfo hints, *all_ai, *resp;
408 char portbuf[10], **errmsgs;
409 int error;
410
411 memset(&hints, 0, sizeof hints);
412 hints.ai_family = af_hint;
413 hints.ai_socktype = type;
414 hints.ai_flags = AI_PASSIVE;
415 snprintf(portbuf, sizeof portbuf, "%d", port);
416 error = getaddrinfo(bind_addr, portbuf, &hints, &all_ai);
417 if (error) {
418 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
419 bind_addr, gai_strerror(error));
420 return NULL;
421 }
422
423 /* Count max number of sockets we might open. */
424 for (maxs = 0, resp = all_ai; resp; resp = resp->ai_next, maxs++) {}
425
426 socks = new_array(int, maxs + 1);
427 errmsgs = new_array(char *, maxs);
428
429 /* We may not be able to create the socket, if for example the
430 * machine knows about IPv6 in the C library, but not in the
431 * kernel. */
432 for (resp = all_ai, i = ecnt = 0; resp; resp = resp->ai_next) {
433 s = socket(resp->ai_family, resp->ai_socktype,
434 resp->ai_protocol);
435
436 if (s == -1) {
437 int r = asprintf(&errmsgs[ecnt++],
438 "socket(%d,%d,%d) failed: %s\n",
439 (int)resp->ai_family, (int)resp->ai_socktype,
440 (int)resp->ai_protocol, strerror(errno));
441 if (r < 0)
442 out_of_memory("open_socket_in");
443 /* See if there's another address that will work... */
444 continue;
445 }
446
447 setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
448 (char *)&one, sizeof one);
449 if (sockopts)
450 set_socket_options(s, sockopts);
451 else
452 set_socket_options(s, lp_socket_options());
453
454#ifdef IPV6_V6ONLY
455 if (resp->ai_family == AF_INET6) {
456 if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&one, sizeof one) < 0
457 && default_af_hint != AF_INET6) {
458 close(s);
459 continue;

Callers 1

start_accept_loopFunction · 0.85

Calls 8

getaddrinfoFunction · 0.85
gai_strerrorFunction · 0.85
asprintfFunction · 0.85
strerrorFunction · 0.85
set_socket_optionsFunction · 0.85
freeaddrinfoFunction · 0.85
rwriteFunction · 0.85
rprintfFunction · 0.70

Tested by

no test coverage detected