/* * Note: this is the old way of resolving a host * that does not use the new getaddrinfo() above. */ static const char *resolv_host(int family, const char *host, dlist * addr_list) { struct hostent *hp; const char *errmsg; P(ip_mutex); /* gethostbyname() is not thread safe */ #ifdef HAVE_GETHOSTBYNAME2 if ((hp = gethostbyname2(host, family)) == NULL) { #else if ((hp = gethostbyname(host)) == NULL) { #endif /* may be the strerror give not the right result -:( */ errmsg = gethost_strerror(); V(ip_mutex); return errmsg; } else { char **p; for (p = hp->h_addr_list; *p != 0; p++) { IPADDR *addr = New(IPADDR(hp->h_addrtype)); addr->set_type(IPADDR::R_MULTIPLE); if (addr->get_family() == AF_INET) { addr->set_addr4((struct in_addr*)*p); addr_list->append(addr); } #ifdef HAVE_IPV6 else if (addr->get_family() == AF_INET6) { addr->set_addr6((struct in6_addr*)*p); addr_list->append(addr); } #endif } V(ip_mutex); } return NULL; } #endif static IPADDR *add_any(int family) { IPADDR *addr = New(IPADDR(family)); addr->set_type(IPADDR::R_MULTIPLE); addr->set_addr_any(); return addr; }
/* * Open a TCP connection to the server * Returns NULL * Returns BSOCK * pointer on success * */ bool BSOCK::open(JCR *jcr, const char *name, char *host, char *service, int port, utime_t heart_beat, int *fatal) { int sockfd = -1; dlist *addr_list; IPADDR *ipaddr; bool connected = false; int turnon = 1; const char *errstr; int save_errno = 0; /* * Fill in the structure serv_addr with the address of * the server that we want to connect with. */ if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) { /* Note errstr is not malloc'ed */ Qmsg2(jcr, M_ERROR, 0, _("gethostbyname() for host \"%s\" failed: ERR=%s\n"), host, errstr); Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n", host, errstr); *fatal = 1; return false; } foreach_dlist(ipaddr, addr_list) { ipaddr->set_port_net(htons(port)); char allbuf[256 * 10]; char curbuf[256]; Dmsg2(100, "Current %sAll %s\n", ipaddr->build_address_str(curbuf, sizeof(curbuf)), build_addresses_str(addr_list, allbuf, sizeof(allbuf))); /* Open a TCP socket */ if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) { berrno be; save_errno = errno; *fatal = 1; Pmsg3(000, _("Socket open error. proto=%d port=%d. ERR=%s\n"), ipaddr->get_family(), ipaddr->get_port_host_order(), be.bstrerror()); continue; } /* Bind to the source address if it is set */ if (src_addr) { if (bind(sockfd, src_addr->get_sockaddr(), src_addr->get_sockaddr_len()) < 0) { berrno be; save_errno = errno; *fatal = 1; Pmsg2(000, _("Source address bind error. proto=%d. ERR=%s\n"), src_addr->get_family(), be.bstrerror() ); continue; } } /* * Keep socket from timing out from inactivity */ if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) { berrno be; Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"), be.bstrerror()); } #if defined(TCP_KEEPIDLE) if (heart_beat) { int opt = heart_beat if (setsockopt(sockfd, IPPROTO_IP, TCP_KEEPIDLE, (sockopt_val_t)&opt, sizeof(opt)) < 0) { berrno be; Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPIDLE on socket: %s\n"), be.bstrerror()); } } #endif /* connect to server */ if (::connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) { save_errno = errno; socketClose(sockfd); continue; } *fatal = 0; connected = true; break; }