2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2008 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 three of the GNU Affero General Public
10 License as published by the Free Software Foundation and included
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 Affero 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 Kern Sibbald.
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 * Adapted and enhanced for Bacula, originally written
34 * for inclusion in the Apcupsd package
45 #define INADDR_NONE -1
49 #define socketRead(fd, buf, len) recv(fd, buf, len, 0)
50 #define socketWrite(fd, buf, len) send(fd, buf, len, 0)
51 #define socketClose(fd) closesocket(fd)
53 #define socketRead(fd, buf, len) read(fd, buf, len)
54 #define socketWrite(fd, buf, len) write(fd, buf, len)
55 #define socketClose(fd) close(fd)
58 static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER;
61 * Read a nbytes from the network.
62 * It is possible that the total bytes require in several
66 int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
73 return (tls_bsock_readn(bsock, ptr, nbytes));
80 nread = socketRead(bsock->m_fd, ptr, nleft);
81 if (bsock->is_timed_out() || bsock->is_terminated()) {
88 if (errno == EAGAIN) {
89 bmicrosleep(0, 20000); /* try again in 20ms */
94 return nread; /* error, or EOF */
98 if (bsock->use_bwlimit()) {
99 bsock->control_bwlimit(nread);
102 return nbytes - nleft; /* return >= 0 */
106 * Write nbytes to the network.
107 * It may require several writes.
110 int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
112 int32_t nleft, nwritten;
114 if (bsock->is_spooling()) {
115 nwritten = fwrite(ptr, 1, nbytes, bsock->m_spool_fd);
116 if (nwritten != nbytes) {
118 bsock->b_errno = errno;
119 Qmsg1(bsock->jcr(), M_FATAL, 0, _("Attr spool write error. ERR=%s\n"),
121 Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
122 errno = bsock->b_errno;
131 return (tls_bsock_writen(bsock, ptr, nbytes));
133 #endif /* HAVE_TLS */
139 nwritten = socketWrite(bsock->m_fd, ptr, nleft);
140 if (bsock->is_timed_out() || bsock->is_terminated()) {
143 } while (nwritten == -1 && errno == EINTR);
145 * If connection is non-blocking, we will get EAGAIN, so
146 * use select() to keep from consuming all the CPU
149 if (nwritten == -1 && errno == EAGAIN) {
154 FD_SET((unsigned)bsock->m_fd, &fdset);
157 select(bsock->m_fd + 1, NULL, &fdset, NULL, &tv);
161 return nwritten; /* error */
165 if (bsock->use_bwlimit()) {
166 bsock->control_bwlimit(nwritten);
169 return nbytes - nleft;
173 * Receive a message from the other end. Each message consists of
174 * two packets. The first is a header that contains the size
175 * of the data that follows in the second packet.
176 * Returns number of bytes read (may return zero)
177 * Returns -1 on signal (BNET_SIGNAL)
178 * Returns -2 on hard end of file (BNET_HARDEOF)
179 * Returns -3 on error (BNET_ERROR)
181 * Unfortunately, it is a bit complicated because we have these
184 * 2. Signal including end of data stream
185 * 3. Hard end of file
187 * Using is_bnet_stop() and is_bnet_error() you can figure this all out.
189 int32_t bnet_recv(BSOCK * bsock)
191 return bsock->recv();
196 * Return 1 if there are errors on this bsock or it is closed,
197 * i.e. stop communicating on this line.
199 bool is_bnet_stop(BSOCK * bsock)
201 return bsock->is_stop();
205 * Return number of errors on socket
207 int is_bnet_error(BSOCK * bsock)
209 return bsock->is_error();
213 * Call here after error during closing to suppress error
214 * messages which are due to the other end shutting down too.
216 void bnet_suppress_error_messages(BSOCK * bsock, bool flag)
218 bsock->m_suppress_error_msgs = flag;
222 * Send a message over the network. The send consists of
223 * two network packets. The first is sends a 32 bit integer containing
224 * the length of the data packet which follows.
226 * Returns: false on failure
229 bool bnet_send(BSOCK *bsock)
231 return bsock->send();
236 * Establish a TLS connection -- server side
237 * Returns: true on success
241 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
244 JCR *jcr = bsock->jcr();
246 tls = new_tls_connection(ctx, bsock->m_fd);
248 Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
254 /* Initiate TLS Negotiation */
255 if (!tls_bsock_accept(bsock)) {
256 Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS Negotiation failed.\n"));
261 if (!tls_postconnect_verify_cn(jcr, tls, verify_list)) {
262 Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed."
263 " Peer certificate did not match a required commonName\n"),
268 Dmsg0(50, "TLS server negotiation established.\n");
272 free_tls_connection(tls);
278 * Establish a TLS connection -- client side
279 * Returns: true on success
282 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
285 JCR *jcr = bsock->jcr();
287 tls = new_tls_connection(ctx, bsock->m_fd);
289 Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
295 /* Initiate TLS Negotiation */
296 if (!tls_bsock_connect(bsock)) {
300 /* If there's an Allowed CN verify list, use that to validate the remote
301 * certificate's CN. Otherwise, we use standard host/CN matching. */
303 if (!tls_postconnect_verify_cn(jcr, tls, verify_list)) {
304 Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed."
305 " Peer certificate did not match a required commonName\n"),
310 if (!tls_postconnect_verify_host(jcr, tls, bsock->host())) {
311 Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS host certificate verification failed. Host name \"%s\" did not match presented certificate\n"),
316 Dmsg0(50, "TLS client negotiation established.\n");
320 free_tls_connection(tls);
326 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
328 Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enabled but not configured.\n"));
332 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
334 Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enable but not configured.\n"));
338 #endif /* HAVE_TLS */
341 * Wait for a specified time for data to appear on
342 * the BSOCK connection.
344 * Returns: 1 if data available
348 int bnet_wait_data(BSOCK * bsock, int sec)
350 return bsock->wait_data(sec);
354 * As above, but returns on interrupt
356 int bnet_wait_data_intr(BSOCK * bsock, int sec)
358 return bsock->wait_data_intr(sec);
361 #ifndef NETDB_INTERNAL
362 #define NETDB_INTERNAL -1 /* See errno. */
364 #ifndef NETDB_SUCCESS
365 #define NETDB_SUCCESS 0 /* No problem. */
367 #ifndef HOST_NOT_FOUND
368 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
371 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
374 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
377 #define NO_DATA 4 /* Valid name, no data record of requested type. */
381 * Get human readable error for gethostbyname()
383 static const char *gethost_strerror()
389 msg = be.bstrerror();
392 msg = _("No problem.");
395 msg = _("Authoritative answer for host not found.");
398 msg = _("Non-authoritative for host not found, or ServerFail.");
401 msg = _("Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.");
404 msg = _("Valid name, no data record of resquested type.");
407 msg = _("Unknown error.");
415 static IPADDR *add_any(int family)
417 IPADDR *addr = New(IPADDR(family));
418 addr->set_type(IPADDR::R_MULTIPLE);
419 addr->set_addr_any();
423 static const char *resolv_host(int family, const char *host, dlist * addr_list)
428 P(ip_mutex); /* gethostbyname() is not thread safe */
429 #ifdef HAVE_GETHOSTBYNAME2
430 if ((hp = gethostbyname2(host, family)) == NULL) {
432 if ((hp = gethostbyname(host)) == NULL) {
434 /* may be the strerror give not the right result -:( */
435 errmsg = gethost_strerror();
440 for (p = hp->h_addr_list; *p != 0; p++) {
441 IPADDR *addr = New(IPADDR(hp->h_addrtype));
442 addr->set_type(IPADDR::R_MULTIPLE);
443 if (addr->get_family() == AF_INET) {
444 addr->set_addr4((struct in_addr*)*p);
448 addr->set_addr6((struct in6_addr*)*p);
451 addr_list->append(addr);
459 * i host = 0 mean INADDR_ANY only ipv4
461 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
463 struct in_addr inaddr;
467 struct in6_addr inaddr6;
470 dlist *addr_list = New(dlist(addr, &addr->link));
471 if (!host || host[0] == '\0') {
473 addr_list->append(add_any(family));
475 addr_list->append(add_any(AF_INET));
477 addr_list->append(add_any(AF_INET6));
480 } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
481 addr = New(IPADDR(AF_INET));
482 addr->set_type(IPADDR::R_MULTIPLE);
483 addr->set_addr4(&inaddr);
484 addr_list->append(addr);
487 if (inet_pton(AF_INET6, host, &inaddr6) > 1) {
488 addr = New(IPADDR(AF_INET6));
489 addr->set_type(IPADDR::R_MULTIPLE);
490 addr->set_addr6(&inaddr6);
491 addr_list->append(addr);
496 errmsg = resolv_host(family, host, addr_list);
499 free_addresses(addr_list);
504 /* We try to resolv host for ipv6 and ipv4, the connection procedure
505 * will try to reach the host for each protocols. We report only "Host
506 * not found" ipv4 message (no need to have ipv6 and ipv4 messages).
508 resolv_host(AF_INET6, host, addr_list);
510 errmsg = resolv_host(AF_INET, host, addr_list);
512 if (addr_list->size() == 0) {
514 free_addresses(addr_list);
523 * This is the "old" way of opening a connection. The preferred way is
524 * now to do what this subroutine does, but inline. That allows the
525 * connect() call to return error status, ...
527 BSOCK *bnet_connect(JCR * jcr, int retry_interval, utime_t max_retry_time,
529 const char *name, char *host, char *service, int port,
532 BSOCK *bsock = new_bsock();
533 if (!bsock->connect(jcr, retry_interval, max_retry_time, heart_beat,
534 name, host, service, port, verbose)) {
544 * Return the string for the error that occurred
545 * on the socket. Only the first error is retained.
547 const char *bnet_strerror(BSOCK * bsock)
549 return bsock->bstrerror();
553 * Format and send a message
554 * Returns: false on error
557 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
562 if (bs->errors || bs->is_terminated()) {
565 /* This probably won't work, but we vsnprintf, then if we
566 * get a negative length or a length greater than our buffer
567 * (depending on which library is used), the printf was truncated, so
568 * get a bigger buffer and try again.
571 maxlen = sizeof_pool_memory(bs->msg) - 1;
572 va_start(arg_ptr, fmt);
573 bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
575 if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
578 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
583 int bnet_get_peer(BSOCK *bs, char *buf, socklen_t buflen)
585 return bs->get_peer(buf, buflen);
589 * Set the network buffer size, suggested size is in size.
590 * Actual size obtained is returned in bs->msglen
592 * Returns: 0 on failure
595 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
597 return bs->set_buffer_size(size, rw);
601 * Set socket non-blocking
602 * Returns previous socket flag
604 int bnet_set_nonblocking(BSOCK *bsock)
606 return bsock->set_nonblocking();
610 * Set socket blocking
611 * Returns previous socket flags
613 int bnet_set_blocking(BSOCK *bsock)
615 return bsock->set_blocking();
619 * Restores socket flags
621 void bnet_restore_blocking (BSOCK *bsock, int flags)
623 bsock->restore_blocking(flags);
628 * Send a network "signal" to the other end
629 * This consists of sending a negative packet length
631 * Returns: false on failure
634 bool bnet_sig(BSOCK * bs, int signal)
636 return bs->signal(signal);
640 * Convert a network "signal" code into
641 * human readable ASCII.
643 const char *bnet_sig_to_ascii(BSOCK * bs)
646 switch (bs->msglen) {
648 return "BNET_EOD"; /* end of data stream */
650 return "BNET_EOD_POLL";
652 return "BNET_STATUS";
654 return "BNET_TERMINATE"; /* terminate connection */
658 return "BNET_HEARTBEAT";
659 case BNET_HB_RESPONSE:
660 return "BNET_HB_RESPONSE";
661 case BNET_SUB_PROMPT:
662 return "BNET_SUB_PROMPT";
663 case BNET_TEXT_INPUT:
664 return "BNET_TEXT_INPUT";
666 sprintf(buf, _("Unknown sig %d"), (int)bs->msglen);
671 /* Initialize internal socket structure.
672 * This probably should be done in net_open
674 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
675 struct sockaddr *client_addr)
677 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
678 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
679 memset(bsock, 0, sizeof(BSOCK));
680 bsock->m_fd = sockfd;
683 bsock->m_blocking = 1;
684 bsock->msg = get_pool_memory(PM_MESSAGE);
685 bsock->errmsg = get_pool_memory(PM_MESSAGE);
686 bsock->set_who(bstrdup(who));
687 bsock->set_host(bstrdup(host));
688 bsock->set_port(port);
689 memset(&bsock->peer_addr, 0, sizeof(bsock->peer_addr));
690 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
692 * ****FIXME**** reduce this to a few hours once
693 * heartbeats are implemented
695 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
700 BSOCK *dup_bsock(BSOCK *osock)
702 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
703 memcpy(bsock, osock, sizeof(BSOCK));
704 bsock->msg = get_pool_memory(PM_MESSAGE);
705 bsock->errmsg = get_pool_memory(PM_MESSAGE);
707 bsock->set_who(bstrdup(osock->who()));
710 bsock->set_host(bstrdup(osock->host()));
712 if (osock->src_addr) {
713 bsock->src_addr = New( IPADDR( *(osock->src_addr)) );
719 /* Close the network connection */
720 void bnet_close(BSOCK * bsock)
725 void term_bsock(BSOCK * bsock)