2 Bacula® - The Network Backup Solution
4 Copyright (C) 2007-2007 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation plus additions
11 that are listed in the file LICENSE.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * Network Utility Routines
33 * Version $Id: bnet.c 3670 2006-11-21 16:13:58Z kerns $
41 #ifndef ENODATA /* not defined on BSD systems */
46 #define socketRead(fd, buf, len) ::recv(fd, buf, len, 0)
47 #define socketWrite(fd, buf, len) ::send(fd, buf, len, 0)
48 #define socketClose(fd) ::closesocket(fd)
50 #define socketRead(fd, buf, len) ::read(fd, buf, len)
51 #define socketWrite(fd, buf, len) ::write(fd, buf, len)
52 #define socketClose(fd) ::close(fd)
57 memset(this, 0, sizeof(BSOCK));
66 * Try to connect to host for max_retry_time at retry_time intervals.
68 bool BSOCK::connect(JCR * jcr, int retry_interval, utime_t max_retry_time,
70 const char *name, char *host, char *service, int port,
76 time_t begin_time = time(NULL);
80 /* Try to trap out of OS call when time expires */
82 tid = start_thread_timer(pthread_self(), (uint32_t)max_retry_time);
85 for (i = 0; !open(jcr, name, host, service, port, heart_beat, &fatal);
86 i -= retry_interval) {
88 if (fatal || (jcr && job_canceled(jcr))) {
91 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
92 name, host, port, be.bstrerror());
94 i = 60 * 5; /* complain again in 5 minutes */
96 Qmsg4(jcr, M_WARNING, 0, _(
97 "Could not connect to %s on %s:%d. ERR=%s\n"
98 "Retrying ...\n"), name, host, port, be.bstrerror());
100 bmicrosleep(retry_interval, 0);
102 if (begin_time + max_retry_time <= now) {
103 Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
104 name, host, port, be.bstrerror());
112 stop_thread_timer(tid);
118 /* Initialize internal socket structure.
119 * This probably should be done in net_open
121 void BSOCK::init(JCR * jcr, int sockfd, const char *who, const char *host, int port,
122 struct sockaddr *lclient_addr)
124 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
129 msg = get_pool_memory(PM_MESSAGE);
130 errmsg = get_pool_memory(PM_MESSAGE);
131 set_who(bstrdup(who));
132 set_host(bstrdup(host));
134 memset(&peer_addr, 0, sizeof(peer_addr));
135 memcpy(&client_addr, lclient_addr, sizeof(client_addr));
137 * ****FIXME**** reduce this to a few hours once
138 * heartbeats are implemented
140 timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
145 * Open a TCP connection to the UPS network server
147 * Returns BSOCK * pointer on success
150 bool BSOCK::open(JCR *jcr, const char *name, char *host, char *service,
151 int port, utime_t heart_beat, int *fatal)
156 bool connected = false;
162 * Fill in the structure serv_addr with the address of
163 * the server that we want to connect with.
165 if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) {
166 /* Note errstr is not malloc'ed */
167 Qmsg2(jcr, M_ERROR, 0, _("gethostbyname() for host \"%s\" failed: ERR=%s\n"),
169 Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n",
175 foreach_dlist(ipaddr, addr_list) {
176 ipaddr->set_port_net(htons(port));
177 char allbuf[256 * 10];
179 Dmsg2(100, "Current %sAll %s\n",
180 ipaddr->build_address_str(curbuf, sizeof(curbuf)),
181 build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
182 /* Open a TCP socket */
183 if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) {
187 Pmsg3(000, _("Socket open error. proto=%d port=%d. ERR=%s\n"),
188 ipaddr->get_family(), ipaddr->get_port_host_order(), be.bstrerror());
192 * Keep socket from timing out from inactivity
194 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
196 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
199 #if defined(TCP_KEEPIDLE)
202 if (setsockopt(sockfd, IPPROTO_IP, TCP_KEEPIDLE, (sockopt_val_t)&opt, sizeof(opt)) < 0) {
204 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPIDLE on socket: %s\n"),
210 /* connect to server */
211 if (::connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) {
222 free_addresses(addr_list);
223 errno = save_errno | b_errno_win32;
227 * Keep socket from timing out from inactivity
228 * Do this a second time out of paranoia
230 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
232 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
235 init(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
236 free_addresses(addr_list);
243 * Send a message over the network. The send consists of
244 * two network packets. The first is sends a 32 bit integer containing
245 * the length of the data packet which follows.
247 * Returns: false on failure
256 if (errors || is_terminated() || msglen > 1000000) {
259 /* Compute total packet length */
261 pktsiz = sizeof(pktsiz); /* signal, no data */
263 pktsiz = msglen + sizeof(pktsiz); /* data */
265 /* Store packet length at head of message -- note, we
266 * have reserved an int32_t just before msg, so we can
269 hdr = (int32_t *)(msg - (int)sizeof(pktsiz));
270 *hdr = htonl(msglen); /* store signal/length */
272 out_msg_no++; /* increment message number */
274 /* send data packet */
275 timer_start = watchdog_time; /* start timer */
277 /* Full I/O done in one write */
278 rc = write_nbytes(this, (char *)hdr, pktsiz);
279 timer_start = 0; /* clear timer */
288 if (!m_suppress_error_msgs) {
289 Qmsg5(m_jcr, M_ERROR, 0,
290 _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"),
292 m_host, m_port, bnet_strerror(this));
295 Qmsg5(m_jcr, M_ERROR, 0,
296 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
297 msglen, m_who, m_host, m_port, rc);
305 * Format and send a message
306 * Returns: false on error
309 bool BSOCK::fsend(const char *fmt, ...)
314 if (errors || is_terminated()) {
317 /* This probably won't work, but we vsnprintf, then if we
318 * get a negative length or a length greater than our buffer
319 * (depending on which library is used), the printf was truncated, so
320 * get a bigger buffer and try again.
323 maxlen = sizeof_pool_memory(msg) - 1;
324 va_start(arg_ptr, fmt);
325 msglen = bvsnprintf(msg, maxlen, fmt, arg_ptr);
327 if (msglen > 0 && msglen < (maxlen - 5)) {
330 msg = realloc_pool_memory(msg, maxlen + maxlen / 2);
336 * Receive a message from the other end. Each message consists of
337 * two packets. The first is a header that contains the size
338 * of the data that follows in the second packet.
339 * Returns number of bytes read (may return zero)
340 * Returns -1 on signal (BNET_SIGNAL)
341 * Returns -2 on hard end of file (BNET_HARDEOF)
342 * Returns -3 on error (BNET_ERROR)
344 * Unfortunately, it is a bit complicated because we have these
347 * 2. Signal including end of data stream
348 * 3. Hard end of file
350 * Using is_bnet_stop() and is_bnet_error() you can figure this all out.
352 int32_t BSOCK::recv()
359 if (errors || is_terminated()) {
363 read_seqno++; /* bump sequence number */
364 timer_start = watchdog_time; /* set start wait time */
366 /* get data size -- in int32_t */
367 if ((nbytes = read_nbytes(this, (char *)&pktsiz, sizeof(int32_t))) <= 0) {
368 timer_start = 0; /* clear timer */
369 /* probably pipe broken because client died */
376 return BNET_HARDEOF; /* assume hard EOF received */
378 timer_start = 0; /* clear timer */
379 if (nbytes != sizeof(int32_t)) {
382 Qmsg5(m_jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
383 sizeof(int32_t), nbytes, m_who, m_host, m_port);
387 pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */
389 if (pktsiz == 0) { /* No data transferred */
390 timer_start = 0; /* clear timer */
393 return 0; /* zero bytes read */
396 /* If signal or packet size too big */
397 if (pktsiz < 0 || pktsiz > 1000000) {
398 if (pktsiz > 0) { /* if packet too big */
399 Qmsg3(m_jcr, M_FATAL, 0,
400 _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"),
401 m_who, m_host, m_port);
402 pktsiz = BNET_TERMINATE; /* hang up */
404 if (pktsiz == BNET_TERMINATE) {
407 timer_start = 0; /* clear timer */
409 msglen = pktsiz; /* signal code */
410 return BNET_SIGNAL; /* signal */
413 /* Make sure the buffer is big enough + one byte for EOS */
414 if (pktsiz >= (int32_t) sizeof_pool_memory(msg)) {
415 msg = realloc_pool_memory(msg, pktsiz + 100);
418 timer_start = watchdog_time; /* set start wait time */
420 /* now read the actual data */
421 if ((nbytes = read_nbytes(this, msg, pktsiz)) <= 0) {
422 timer_start = 0; /* clear timer */
429 Qmsg4(m_jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"),
430 m_who, m_host, m_port, bnet_strerror(this));
433 timer_start = 0; /* clear timer */
436 if (nbytes != pktsiz) {
439 Qmsg5(m_jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
440 pktsiz, nbytes, m_who, m_host, m_port);
443 /* always add a zero by to properly terminate any
444 * string that was send to us. Note, we ensured above that the
445 * buffer is at least one byte longer than the message length.
447 msg[nbytes] = 0; /* terminate in case it is a string */
448 sm_check(__FILE__, __LINE__, false);
449 return nbytes; /* return actual length of message */
456 bool BSOCK::signal(int signal)
459 if (signal == BNET_TERMINATE) {
460 m_suppress_error_msgs = true;
466 * Despool spooled attributes
468 bool BSOCK::despool(void update_attr_spool_size(ssize_t size), ssize_t tsize)
472 ssize_t last = 0, size = 0;
477 #if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
478 posix_fadvise(fileno(m_spool_fd), 0, 0, POSIX_FADV_WILLNEED);
481 while (fread((char *)&pktsiz, 1, sizeof(int32_t), m_spool_fd) ==
483 size += sizeof(int32_t);
484 msglen = ntohl(pktsiz);
486 if (msglen > (int32_t) sizeof_pool_memory(msg)) {
487 msg = realloc_pool_memory(msg, msglen + 1);
489 nbytes = fread(msg, 1, msglen, m_spool_fd);
490 if (nbytes != (size_t) msglen) {
492 Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, msglen);
493 Qmsg1(get_jcr(), M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
495 update_attr_spool_size(tsize - last);
499 if ((++count & 0x3F) == 0) {
500 update_attr_spool_size(size - last);
506 update_attr_spool_size(tsize - last);
507 if (ferror(m_spool_fd)) {
509 Qmsg1(get_jcr(), M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
517 * Return the string for the error that occurred
518 * on the socket. Only the first error is retained.
520 const char *BSOCK::bstrerror()
523 if (errmsg == NULL) {
524 errmsg = get_pool_memory(PM_MESSAGE);
526 pm_strcpy(errmsg, be.bstrerror(b_errno));
530 int BSOCK::get_peer(char *buf, socklen_t buflen)
532 #if !defined(HAVE_WIN32)
533 if (peer_addr.sin_family == 0) {
534 socklen_t salen = sizeof(peer_addr);
535 int rval = (getpeername)(m_fd, (struct sockaddr *)&peer_addr, &salen);
536 if (rval < 0) return rval;
538 if (!inet_ntop(peer_addr.sin_family, &peer_addr.sin_addr, buf, buflen))
548 * Set the network buffer size, suggested size is in size.
549 * Actual size obtained is returned in bs->msglen
551 * Returns: false on failure
554 bool BSOCK::set_buffer_size(uint32_t size, int rw)
556 uint32_t dbuf_size, start_size;
557 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
559 opt = IPTOS_THROUGHPUT;
560 setsockopt(fd, IPPROTO_IP, IP_TOS, (sockopt_val_t)&opt, sizeof(opt));
566 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
568 start_size = dbuf_size;
569 if ((msg = realloc_pool_memory(msg, dbuf_size + 100)) == NULL) {
570 Qmsg0(get_jcr(), M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
573 if (rw & BNET_SETBUF_READ) {
574 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(m_fd, SOL_SOCKET,
575 SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
577 Qmsg1(get_jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.bstrerror());
578 dbuf_size -= TAPE_BSIZE;
580 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
581 if (dbuf_size != start_size) {
582 Qmsg1(get_jcr(), M_WARNING, 0,
583 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
585 if (dbuf_size % TAPE_BSIZE != 0) {
586 Qmsg1(get_jcr(), M_ABORT, 0,
587 _("Network buffer size %d not multiple of tape block size.\n"),
594 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
596 start_size = dbuf_size;
597 if (rw & BNET_SETBUF_WRITE) {
598 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(m_fd, SOL_SOCKET,
599 SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
601 Qmsg1(get_jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.bstrerror());
602 dbuf_size -= TAPE_BSIZE;
604 Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
605 if (dbuf_size != start_size) {
606 Qmsg1(get_jcr(), M_WARNING, 0,
607 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
609 if (dbuf_size % TAPE_BSIZE != 0) {
610 Qmsg1(get_jcr(), M_ABORT, 0,
611 _("Network buffer size %d not multiple of tape block size.\n"),
621 * Set socket non-blocking
622 * Returns previous socket flag
624 int BSOCK::set_nonblocking()
629 /* Get current flags */
630 if ((oflags = fcntl(m_fd, F_GETFL, 0)) < 0) {
632 Jmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.bstrerror());
635 /* Set O_NONBLOCK flag */
636 if ((fcntl(m_fd, F_SETFL, oflags|O_NONBLOCK)) < 0) {
638 Jmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.bstrerror());
648 ioctlsocket(m_fd, FIONBIO, &ioctlArg);
656 * Set socket blocking
657 * Returns previous socket flags
659 int BSOCK::set_blocking()
663 /* Get current flags */
664 if ((oflags = fcntl(m_fd, F_GETFL, 0)) < 0) {
666 Jmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.bstrerror());
669 /* Set O_NONBLOCK flag */
670 if ((fcntl(m_fd, F_SETFL, oflags & ~O_NONBLOCK)) < 0) {
672 Jmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.bstrerror());
682 ioctlsocket(m_fd, FIONBIO, &ioctlArg);
690 * Restores socket flags
692 void BSOCK::restore_blocking (int flags)
695 if ((fcntl(m_fd, F_SETFL, flags)) < 0) {
697 Jmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.bstrerror());
700 m_blocking = (flags & O_NONBLOCK) ? true : false;
702 u_long ioctlArg = flags;
704 ioctlsocket(m_fd, FIONBIO, &ioctlArg);
715 for (; bsock; bsock = next) {
716 next = bsock->m_next; /* get possible pointer to next before destoryed */
717 if (!bsock->m_duped) {
719 /* Shutdown tls cleanly. */
721 tls_bsock_shutdown(bsock);
722 free_tls_connection(bsock->tls);
725 #endif /* HAVE_TLS */
726 if (bsock->is_timed_out()) {
727 shutdown(bsock->m_fd, 2); /* discard any pending I/O */
729 socketClose(bsock->m_fd); /* normal close */
731 bsock->destroy(); /* free the packet */
736 void BSOCK::destroy()
739 free_pool_memory(msg);
742 ASSERT(1 == 0); /* double close */
745 free_pool_memory(errmsg);