#endif
+#ifdef HAVE_OLD_SOCKOPT
+int inet_aton(const char *cp, struct in_addr *inp)
+{
+ struct in_addr inaddr;
+
+ if((inaddr.s_addr = inet_addr(cp)) != INADDR_NONE) {
+ inp->s_addr = inaddr.s_addr;
+ return 1;
+ }
+ return 0;
+}
+#endif
+
/*
* Read a nbytes from the network.
* It is possible that the total bytes require in several
nwritten = fwrite(ptr, 1, nbytes, bsock->spool_fd);
if (nwritten != nbytes) {
berrno be;
+ bsock->b_errno = errno;
Qmsg1(bsock->jcr, M_FATAL, 0, _("Attr spool write error. ERR=%s\n"),
be.strerror());
Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
+ errno = bsock->b_errno;
return -1;
}
return nbytes;
int32_t pktsiz;
ASSERT(bsock != NULL);
- mp_chr(bsock->msg)[0] = 0;
+ bsock->msg[0] = 0;
+ bsock->msglen = 0;
if (bsock->errors || bsock->terminated) {
return BNET_HARDEOF;
}
bsock->timer_start = watchdog_time; /* set start wait time */
bsock->timed_out = 0;
/* now read the actual data */
- if ((nbytes = read_nbytes(bsock, mp_chr(bsock->msg), pktsiz)) <= 0) {
+ if ((nbytes = read_nbytes(bsock, bsock->msg, pktsiz)) <= 0) {
bsock->timer_start = 0; /* clear timer */
if (errno == 0) {
bsock->b_errno = ENODATA;
* string that was send to us. Note, we ensured above that the
* buffer is at least one byte longer than the message length.
*/
- mp_chr(bsock->msg)[nbytes] = 0; /* terminate in case it is a string */
+ bsock->msg[nbytes] = 0; /* terminate in case it is a string */
sm_check(__FILE__, __LINE__, false);
return nbytes; /* return actual length of message */
}
* two network packets. The first is sends a 32 bit integer containing
* the length of the data packet which follows.
*
- * Returns: 0 on failure
- * 1 on success
+ * Returns: false on failure
+ * true on success
*/
bool bnet_send(BSOCK * bsock)
{
/* send data packet */
bsock->timer_start = watchdog_time; /* start timer */
bsock->timed_out = 0;
- rc = write_nbytes(bsock, mp_chr(bsock->msg), bsock->msglen);
+ rc = write_nbytes(bsock, bsock->msg, bsock->msglen);
bsock->timer_start = 0; /* clear timer */
if (rc != bsock->msglen) {
bsock->errors++;
*/
static const char *gethost_strerror()
{
+ const char *msg;
switch (h_errno) {
case NETDB_INTERNAL:
- return strerror(errno);
+ msg = strerror(errno);
+ break;
case NETDB_SUCCESS:
- return "No problem.";
+ msg = "No problem.";
+ break;
case HOST_NOT_FOUND:
- return "Authoritative answer Host not found.";
+ msg = "Authoritative answer for host not found.";
+ break;
case TRY_AGAIN:
- return "Non-authoritative Host not found, or ServerFail.";
+ msg = "Non-authoritative for host not found, or ServerFail.";
+ break;
case NO_RECOVERY:
- return "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.";
+ msg = "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.";
+ break;
case NO_DATA:
- return "Valid name, no data record of resquested type.";
+ msg = "Valid name, no data record of resquested type.";
+ break;
default:
- return "Unknown error.";
+ msg = "Unknown error.";
}
+ return msg;
}
static IPADDR *add_any(int family)
{
- IPADDR *addr = new IPADDR(family);
+ IPADDR *addr = New(IPADDR(family));
addr->set_type(IPADDR::R_MULTIPLE);
addr->set_addr_any();
return addr;
}
-static int resolv_host(int family, const char *host, dlist * addr_list,
- const char **errstr)
+static const char *resolv_host(int family, const char *host, dlist * addr_list)
{
struct hostent *hp;
+ const char *errmsg;
P(ip_mutex);
#ifdef HAVE_GETHOSTBYNAME2
if ((hp = gethostbyname(host)) == NULL) {
#endif
/* may be the strerror give not the right result -:( */
- *errstr = gethost_strerror();
+ errmsg = gethost_strerror();
V(ip_mutex);
- return 0;
+ return errmsg;
} else {
char **p;
for (p = hp->h_addr_list; *p != 0; p++) {
- IPADDR *addr = new IPADDR(hp->h_addrtype);
+ 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);
}
V(ip_mutex);
}
- return 1;
+ return NULL;
}
/*
{
struct in_addr inaddr;
IPADDR *addr = 0;
+ const char *errmsg;
#ifdef HAVE_IPV6
struct in6_addr inaddr6;
#endif
- dlist *addr_list = new dlist(addr, &addr->link);
+ dlist *addr_list = New(dlist(addr, &addr->link));
if (!host || host[0] == '\0') {
if (family != 0) {
addr_list->append(add_any(family));
addr_list->append(add_any(AF_INET6));
#endif
}
- } else if ((inaddr.s_addr = inet_addr(host)) != INADDR_NONE) {
- addr = new IPADDR(AF_INET);
+ } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
+ addr = New(IPADDR(AF_INET));
addr->set_type(IPADDR::R_MULTIPLE);
addr->set_addr4(&inaddr);
addr_list->append(addr);
} else
#ifdef HAVE_IPV6
if (inet_pton(AF_INET6, host, &inaddr6) > 1) {
- addr = new IPADDR(AF_INET6);
+ addr = New(IPADDR(AF_INET6));
addr->set_type(IPADDR::R_MULTIPLE);
addr->set_addr6(&inaddr6);
addr_list->append(addr);
#endif
{
if (family != 0) {
- if (!resolv_host(family, host, addr_list, errstr)) {
+ errmsg = resolv_host(family, host, addr_list);
+ if (errmsg) {
+ *errstr = errmsg;
free_addresses(addr_list);
return 0;
}
} else {
- int done = 0;
- done |= resolv_host(AF_INET, host, addr_list, errstr);
+ errmsg = resolv_host(AF_INET, host, addr_list);
#ifdef HAVE_IPV6
- done |= resolv_host(AF_INET6, host, addr_list, errstr);
+ if (errmsg) {
+ errmsg = resolv_host(AF_INET6, host, addr_list);
+ }
#endif
- if (!done) {
+ if (errmsg) {
+ *errstr = errmsg;
free_addresses(addr_list);
return 0;
}
* 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);
- free((void *)errstr);
+ Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n",
+ host, errstr);
*fatal = 1;
return NULL;
}
foreach_dlist(ipaddr, addr_list) {
- ipaddr->set_port(htons(port));
+ ipaddr->set_port_net(htons(port));
char allbuf[256 * 10];
char curbuf[256];
Dmsg2(100, "Current %sAll %s\n",
save_errno = errno;
*fatal = 1;
Pmsg3(000, "Socket open error. proto=%d port=%d. ERR=%s\n",
- ipaddr->get_family(), ipaddr->get_port(), be.strerror());
+ ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror());
continue;
}
/*
- * Receive notification when connection dies.
+ * Keep socket from timing out from inactivity
*/
- if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t) & turnon,
- sizeof(turnon)) < 0) {
+ 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.strerror());
break;
}
- free_addresses(addr_list);
if (!connected) {
+ free_addresses(addr_list);
errno = save_errno;
return NULL;
}
- return init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
+ /*
+ * Keep socket from timing out from inactivity
+ * Do this a second time out of paranoia
+ */
+ 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.strerror());
+ }
+ BSOCK* ret = init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
+ free_addresses(addr_list);
+ return ret;
}
/*
* Return the string for the error that occurred
* on the socket. Only the first error is retained.
*/
-char *bnet_strerror(BSOCK * bsock)
+const char *bnet_strerror(BSOCK * bsock)
{
- return strerror(bsock->b_errno);
+ berrno be;
+ if (bsock->errmsg == NULL) {
+ bsock->errmsg = get_pool_memory(PM_MESSAGE);
+ }
+ pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
+ return bsock->errmsg;
}
/*
for (;;) {
maxlen = sizeof_pool_memory(bs->msg) - 1;
va_start(arg_ptr, fmt);
- bs->msglen = bvsnprintf(mp_chr(bs->msg), maxlen, fmt, arg_ptr);
+ bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
va_end(arg_ptr);
if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
break;
* This probably should be done in net_open
*/
BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
- struct sockaddr * client_addr)
+ struct sockaddr *client_addr)
{
+ Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
memset(bsock, 0, sizeof(BSOCK));
bsock->fd = sockfd;