1 /*
2    BAREOS® - Backup Archiving REcovery Open Sourced
3 
4    Copyright (C) 2007-2011 Free Software Foundation Europe e.V.
5    Copyright (C) 2013-2019 Bareos GmbH & Co. KG
6 
7    This program is Free Software; you can redistribute it and/or
8    modify it under the terms of version three of the GNU Affero General Public
9    License as published by the Free Software Foundation and included
10    in the file LICENSE.
11 
12    This program is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15    Affero General Public License for more details.
16 
17    You should have received a copy of the GNU Affero General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20    02110-1301, USA.
21 */
22 /*
23  * TCP Sockets abstraction.
24  *
25  * Kern Sibbald
26  *
27  * Extracted from other source files by Marco van Wieringen, September 2013.
28  */
29 
30 #include "include/bareos.h"
31 #include "include/jcr.h"
32 #include <netdb.h>
33 #include <netinet/tcp.h>
34 #include "lib/bnet.h"
35 #include "lib/bpoll.h"
36 #include "lib/btimers.h"
37 #include "lib/tls_openssl.h"
38 #include "lib/bsock_tcp.h"
39 #include "lib/berrno.h"
40 
41 #ifndef ENODATA /* not defined on BSD systems */
42 #  define ENODATA EPIPE
43 #endif
44 
45 #ifndef SOL_TCP
46 #  define SOL_TCP IPPROTO_TCP
47 #endif
48 
49 #ifdef HAVE_WIN32
50 #  define socketRead(fd, buf, len) ::recv(fd, buf, len, 0)
51 #  define socketWrite(fd, buf, len) ::send(fd, buf, len, 0)
52 #  define socketClose(fd) ::closesocket(fd)
53 #else
54 #  define socketRead(fd, buf, len) ::read(fd, buf, len)
55 #  define socketWrite(fd, buf, len) ::write(fd, buf, len)
56 #  define socketClose(fd) ::close(fd)
57 #endif
58 
BareosSocketTCP()59 BareosSocketTCP::BareosSocketTCP() : BareosSocket() {}
60 
~BareosSocketTCP()61 BareosSocketTCP::~BareosSocketTCP() { destroy(); }
62 
clone()63 BareosSocket* BareosSocketTCP::clone()
64 {
65   BareosSocketTCP* clone = new BareosSocketTCP(*this);
66 
67   /* do not use memory buffer from copied socket */
68   clone->msg = GetPoolMemory(PM_BSOCK);
69   clone->errmsg = GetPoolMemory(PM_MESSAGE);
70 
71   if (src_addr) { src_addr = new IPADDR(*(src_addr)); }
72   if (who_) { who_ = strdup(who_); }
73   if (host_) { host_ = strdup(host_); }
74 
75   /* duplicate file descriptors */
76   if (fd_ >= 0) { clone->fd_ = dup(fd_); }
77   if (spool_fd_ >= 0) { clone->spool_fd_ = dup(spool_fd_); }
78 
79   clone->cloned_ = true;
80 
81   return clone;
82 }
83 
84 /*
85  * Try to connect to host for max_retry_time at retry_time intervals.
86  * Note, you must have called the constructor prior to calling
87  * this routine.
88  */
connect(JobControlRecord * jcr,int retry_interval,utime_t max_retry_time,utime_t heart_beat,const char * name,const char * host,char * service,int port,bool verbose)89 bool BareosSocketTCP::connect(JobControlRecord* jcr,
90                               int retry_interval,
91                               utime_t max_retry_time,
92                               utime_t heart_beat,
93                               const char* name,
94                               const char* host,
95                               char* service,
96                               int port,
97                               bool verbose)
98 {
99   bool ok = false;
100   int i;
101   int fatal = 0;
102   time_t begin_time = time(NULL);
103   time_t now;
104   btimer_t* tid = NULL;
105 
106   /*
107    * Try to trap out of OS call when time expires
108    */
109   if (max_retry_time) {
110     tid = start_thread_timer(jcr, pthread_self(), (uint32_t)max_retry_time);
111   }
112 
113   for (i = 0; !open(jcr, name, host, service, port, heart_beat, &fatal);
114        i -= retry_interval) {
115     BErrNo be;
116     if (fatal || (jcr && JobCanceled(jcr))) { goto bail_out; }
117     Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n", name, host, port,
118           be.bstrerror());
119     if (i < 0) {
120       i = 60 * 5; /* complain again in 5 minutes */
121       if (verbose)
122         Qmsg4(jcr, M_WARNING, 0,
123               _("Could not connect to %s on %s:%d. ERR=%s\n"
124                 "Retrying ...\n"),
125               name, host, port, be.bstrerror());
126     }
127     Bmicrosleep(retry_interval, 0);
128     now = time(NULL);
129     if (begin_time + max_retry_time <= now) {
130       Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
131             name, host, port, be.bstrerror());
132       goto bail_out;
133     }
134   }
135   ok = true;
136 
137 bail_out:
138   if (tid) { StopThreadTimer(tid); }
139   return ok;
140 }
141 
142 /*
143  * Finish initialization of the pocket structure.
144  */
FinInit(JobControlRecord * jcr,int sockfd,const char * who,const char * host,int port,struct sockaddr * lclient_addr)145 void BareosSocketTCP::FinInit(JobControlRecord* jcr,
146                               int sockfd,
147                               const char* who,
148                               const char* host,
149                               int port,
150                               struct sockaddr* lclient_addr)
151 {
152   Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
153   SetWho(strdup(who));
154   SetHost(strdup(host));
155   SetPort(port);
156   memcpy(&client_addr, lclient_addr, sizeof(client_addr));
157   SetJcr(jcr);
158 }
159 
160 /*
161  * Open a TCP connection to the server
162  *
163  * Returns NULL
164  * Returns BareosSocket * pointer on success
165  */
open(JobControlRecord * jcr,const char * name,const char * host,char * service,int port,utime_t heart_beat,int * fatal)166 bool BareosSocketTCP::open(JobControlRecord* jcr,
167                            const char* name,
168                            const char* host,
169                            char* service,
170                            int port,
171                            utime_t heart_beat,
172                            int* fatal)
173 {
174   int sockfd = -1;
175   dlist* addr_list;
176   IPADDR *ipaddr, *next, *to_free;
177   bool connected = false;
178   int value;
179   const char* errstr;
180   int save_errno = 0;
181 
182   /*
183    * Fill in the structure serv_addr with the address of
184    * the server that we want to connect with.
185    */
186   if ((addr_list = BnetHost2IpAddrs(host, 0, &errstr)) == NULL) {
187     /*
188      * Note errstr is not malloc'ed
189      */
190     Qmsg2(jcr, M_ERROR, 0,
191           _("BnetHost2IpAddrs() for host \"%s\" failed: ERR=%s\n"), host,
192           errstr);
193     Dmsg2(100, "BnetHost2IpAddrs() for host %s failed: ERR=%s\n", host, errstr);
194     *fatal = 1;
195     return false;
196   }
197 
198   /*
199    * Remove any duplicate addresses.
200    */
201   for (ipaddr = (IPADDR*)addr_list->first(); ipaddr;
202        ipaddr = (IPADDR*)addr_list->next(ipaddr)) {
203     next = (IPADDR*)addr_list->next(ipaddr);
204     while (next) {
205       /*
206        * See if the addresses match.
207        */
208       if (ipaddr->GetSockaddrLen() == next->GetSockaddrLen()
209           && memcmp(ipaddr->get_sockaddr(), next->get_sockaddr(),
210                     ipaddr->GetSockaddrLen())
211                  == 0) {
212         to_free = next;
213         next = (IPADDR*)addr_list->next(next);
214         addr_list->remove(to_free);
215         delete to_free;
216       } else {
217         next = (IPADDR*)addr_list->next(next);
218       }
219     }
220   }
221 
222   if (use_keepalive_) {
223     value = 1;
224   } else {
225     value = 0;
226   }
227 
228   foreach_dlist (ipaddr, addr_list) {
229     ipaddr->SetPortNet(htons(port));
230     char allbuf[256 * 10];
231     char curbuf[256];
232     Dmsg2(100, "Current %s All %s\n",
233           ipaddr->build_address_str(curbuf, sizeof(curbuf)),
234           BuildAddressesString(addr_list, allbuf, sizeof(allbuf)));
235     /* Open a TCP socket */
236     if ((sockfd = socket(ipaddr->GetFamily(), SOCK_STREAM, 0)) < 0) {
237       BErrNo be;
238       save_errno = errno;
239       switch (errno) {
240 #ifdef EPFNOSUPPORT
241         case EPFNOSUPPORT:
242           /*
243            * The name lookup of the host returned an address in a protocol
244            * family we don't support. Suppress the error and try the next
245            * address.
246            */
247           break;
248 #endif
249 #ifdef EAFNOSUPPORT
250         case EAFNOSUPPORT:
251           /*
252            * The name lookup of the host returned an address in a address family
253            * we don't support. Suppress the error and try the next address.
254            */
255           break;
256 #endif
257         default:
258           *fatal = 1;
259           Pmsg3(000, _("Socket open error. proto=%d port=%d. ERR=%s\n"),
260                 ipaddr->GetFamily(), ipaddr->GetPortHostOrder(),
261                 be.bstrerror());
262           break;
263       }
264       continue;
265     }
266 
267     /*
268      * Bind to the source address if it is set
269      */
270     if (src_addr) {
271       if (bind(sockfd, src_addr->get_sockaddr(), src_addr->GetSockaddrLen())
272           < 0) {
273         BErrNo be;
274         save_errno = errno;
275         *fatal = 1;
276         Pmsg2(000, _("Source address bind error. proto=%d. ERR=%s\n"),
277               src_addr->GetFamily(), be.bstrerror());
278         if (sockfd >= 0) {
279           socketClose(sockfd);
280           sockfd = -1;
281         }
282         continue;
283       }
284     }
285 
286     /*
287      * Keep socket from timing out from inactivity
288      */
289     SetKeepalive(jcr, sockfd, use_keepalive_, heart_beat, heart_beat);
290 
291     /*
292      * Connect to server
293      */
294     if (::connect(sockfd, ipaddr->get_sockaddr(), ipaddr->GetSockaddrLen())
295         < 0) {
296       save_errno = errno;
297       if (sockfd >= 0) {
298         socketClose(sockfd);
299         sockfd = -1;
300       }
301       continue;
302     }
303     *fatal = 0;
304     connected = true;
305     break;
306   }
307 
308   if (!connected) {
309     FreeAddresses(addr_list);
310     errno = save_errno | b_errno_win32;
311     if (sockfd >= 0) {
312       socketClose(sockfd);
313       sockfd = -1;
314     }
315     return false;
316   }
317 
318   /*
319    * Keep socket from timing out from inactivity
320    * Do this a second time out of paranoia
321    */
322   if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&value,
323                  sizeof(value))
324       < 0) {
325     BErrNo be;
326     Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
327           be.bstrerror());
328   }
329 
330   FinInit(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
331   FreeAddresses(addr_list);
332   fd_ = sockfd;
333   return true;
334 }
335 
336 
SetKeepalive(JobControlRecord * jcr,int sockfd,bool enable,int keepalive_start,int keepalive_interval)337 bool BareosSocketTCP::SetKeepalive(JobControlRecord* jcr,
338                                    int sockfd,
339                                    bool enable,
340                                    int keepalive_start,
341                                    int keepalive_interval)
342 {
343   int value = int(enable);
344 
345   /*
346    * Keep socket from timing out from inactivity
347    */
348   if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&value,
349                  sizeof(value))
350       < 0) {
351     BErrNo be;
352     Qmsg1(jcr, M_WARNING, 0, _("Failed to set SO_KEEPALIVE on socket: %s\n"),
353           be.bstrerror());
354     return false;
355   }
356 
357   if (enable && keepalive_interval) {
358 #ifdef HAVE_WIN32
359     struct s_tcp_keepalive {
360       u_long onoff;
361       u_long keepalivetime;
362       u_long keepaliveinterval;
363     } val;
364     val.onoff = enable;
365     val.keepalivetime = keepalive_start * 1000L;
366     val.keepaliveinterval = keepalive_interval * 1000L;
367     DWORD got = 0;
368     if (WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, &val, sizeof(val), NULL, 0, &got,
369                  NULL, NULL)
370         != 0) {
371       Qmsg1(jcr, M_WARNING, 0,
372             "Failed to set SIO_KEEPALIVE_VALS on socket: %d\n",
373             WSAGetLastError());
374       return false;
375     }
376 #else
377 #  if defined(TCP_KEEPIDLE)
378     if (setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE,
379                    (sockopt_val_t)&keepalive_start, sizeof(keepalive_start))
380         < 0) {
381       BErrNo be;
382       Qmsg2(jcr, M_WARNING, 0,
383             _("Failed to set TCP_KEEPIDLE = %d on socket: %s\n"),
384             keepalive_start, be.bstrerror());
385       return false;
386     }
387     if (setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL,
388                    (sockopt_val_t)&keepalive_interval,
389                    sizeof(keepalive_interval))
390         < 0) {
391       BErrNo be;
392       Qmsg2(jcr, M_WARNING, 0,
393             _("Failed to set TCP_KEEPINTVL = %d on socket: %s\n"),
394             keepalive_interval, be.bstrerror());
395       return false;
396     }
397 #  endif
398 #endif
399   }
400   return true;
401 }
402 
403 
SendPacket(int32_t * hdr,int32_t pktsiz)404 bool BareosSocketTCP::SendPacket(int32_t* hdr, int32_t pktsiz)
405 {
406   Enter(400);
407 
408   int32_t rc;
409   bool ok = true;
410 
411   out_msg_no++; /* increment message number */
412 
413   /*
414    * Send data packet
415    */
416   timer_start = watchdog_time; /* start timer */
417   ClearTimedOut();
418 
419   /*
420    * Full I/O done in one write
421    */
422   rc = write_nbytes((char*)hdr, pktsiz);
423   timer_start = 0; /* clear timer */
424   if (rc != pktsiz) {
425     errors++;
426     if (errno == 0) {
427       b_errno = EIO;
428     } else {
429       b_errno = errno;
430     }
431     if (rc < 0) {
432       if (!suppress_error_msgs_) {
433         Qmsg5(jcr_, M_ERROR, 0,
434               _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"),
435               message_length, who_, host_, port_, this->bstrerror());
436       }
437     } else {
438       Qmsg5(jcr_, M_ERROR, 0,
439             _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
440             message_length, who_, host_, port_, rc);
441     }
442     ok = false;
443   }
444 
445   Leave(400);
446 
447   return ok;
448 }
449 
450 /*
451  * Send a message over the network. The send consists of
452  * two network packets. The first is sends a 32 bit integer containing
453  * the length of the data packet which follows.
454  *
455  * Returns: false on failure
456  *          true  on success
457  */
send()458 bool BareosSocketTCP::send()
459 {
460   /*
461    * Send msg (length: message_length).
462    * As send() and recv() uses the same buffer (msg and message_length)
463    * store the original message_length in an own variable,
464    * that will not be modifed by recv().
465    */
466   const int32_t o_msglen = message_length;
467   int32_t pktsiz;
468   int32_t written = 0;
469   int32_t packet_msglen = 0;
470   bool ok = true;
471   /*
472    * Store packet length at head of message -- note, we have reserved an int32_t
473    * just before msg, So we can store there
474    */
475   int32_t* hdr = (int32_t*)(msg - (int)header_length);
476 
477   if (errors) {
478     if (!suppress_error_msgs_) {
479       Qmsg4(jcr_, M_ERROR, 0, _("Socket has errors=%d on call to %s:%s:%d\n"),
480             errors, who_, host_, port_);
481     }
482     return false;
483   }
484 
485   if (IsTerminated()) {
486     if (!suppress_error_msgs_) {
487       Qmsg4(jcr_, M_ERROR, 0,
488             _("Socket is terminated=%d on call to %s:%s:%d\n"), IsTerminated(),
489             who_, host_, port_);
490     }
491     return false;
492   }
493 
494   LockMutex();
495 
496   /*
497    * Compute total packet length
498    */
499   if (o_msglen <= 0) {
500     pktsiz = header_length; /* signal, no data */
501     *hdr = htonl(o_msglen); /* store signal */
502     ok = SendPacket(hdr, pktsiz);
503   } else {
504     /*
505      * msg might be to long for a single Bareos packet.
506      * If so, send msg as multiple packages.
507      */
508     while (ok && (written < o_msglen)) {
509       if ((o_msglen - written) > max_message_len) {
510         /*
511          * Message is to large for a single Bareos packet.
512          * Send it via multiple packets.
513          */
514         pktsiz = max_packet_size; /* header + data */
515         packet_msglen = max_message_len;
516       } else {
517         /*
518          * Remaining message fits into one Bareos packet
519          */
520         pktsiz = header_length + (o_msglen - written); /* header + data */
521         packet_msglen = (o_msglen - written);
522       }
523 
524       *hdr = htonl(packet_msglen); /* store length */
525       ok = SendPacket(hdr, pktsiz);
526       written += packet_msglen;
527       hdr = (int32_t*)(msg + written - (int)header_length);
528     }
529   }
530 
531   UnlockMutex();
532 
533   return ok;
534 }
535 
536 /*
537  * Receive a message from the other end. Each message consists of
538  * two packets. The first is a header that contains the size
539  * of the data that follows in the second packet.
540  * Returns number of bytes read (may return zero)
541  * Returns -1 on signal (BNET_SIGNAL)
542  * Returns -2 on hard end of file (BNET_HARDEOF)
543  * Returns -3 on error  (BNET_ERROR)
544  *
545  *  Unfortunately, it is a bit complicated because we have these
546  *    four return types:
547  *    1. Normal data
548  *    2. Signal including end of data stream
549  *    3. Hard end of file
550  *    4. Error
551  *  Using IsBnetStop() and IsBnetError() you can figure this all out.
552  */
recv()553 int32_t BareosSocketTCP::recv()
554 {
555   int32_t nbytes;
556   int32_t pktsiz;
557 
558   msg[0] = 0;
559   message_length = 0;
560   if (errors || IsTerminated()) { return BNET_HARDEOF; }
561 
562   if (mutex_) { mutex_->lock(); }
563 
564   read_seqno++;                /* bump sequence number */
565   timer_start = watchdog_time; /* set start wait time */
566   ClearTimedOut();
567 
568   /*
569    * Get data size -- in int32_t
570    */
571   if ((nbytes = read_nbytes((char*)&pktsiz, header_length)) <= 0) {
572     timer_start = 0; /* clear timer */
573     /*
574      * Probably pipe broken because client died
575      */
576     if (errno == 0) {
577       b_errno = ENODATA;
578     } else {
579       b_errno = errno;
580     }
581     errors++;
582     nbytes = BNET_HARDEOF; /* assume hard EOF received */
583     goto get_out;
584   }
585   timer_start = 0; /* clear timer */
586   if (nbytes != header_length) {
587     errors++;
588     b_errno = EIO;
589     Qmsg5(jcr_, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
590           header_length, nbytes, who_, host_, port_);
591     nbytes = BNET_ERROR;
592     goto get_out;
593   }
594 
595   pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */
596 
597   if (pktsiz == 0) { /* No data transferred */
598     timer_start = 0; /* clear timer */
599     in_msg_no++;
600     message_length = 0;
601     nbytes = 0; /* zero bytes read */
602     goto get_out;
603   }
604 
605   /*
606    * If signal or packet size too big
607    */
608   if (pktsiz < 0 || pktsiz > max_packet_size) {
609     if (pktsiz > 0) { /* if packet too big */
610       Qmsg3(jcr_, M_FATAL, 0,
611             _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"),
612             who_, host_, port_);
613       pktsiz = BNET_TERMINATE; /* hang up */
614     }
615     if (pktsiz == BNET_TERMINATE) { SetTerminated(); }
616     timer_start = 0; /* clear timer */
617     b_errno = ENODATA;
618     message_length = pktsiz; /* signal code */
619     nbytes = BNET_SIGNAL;    /* signal */
620     goto get_out;
621   }
622 
623   /*
624    * Make sure the buffer is big enough + one byte for EOS
625    */
626   if (pktsiz >= (int32_t)SizeofPoolMemory(msg)) {
627     msg = ReallocPoolMemory(msg, pktsiz + 100);
628   }
629 
630   timer_start = watchdog_time; /* set start wait time */
631   ClearTimedOut();
632 
633   /*
634    * Now read the actual data
635    */
636   if ((nbytes = read_nbytes(msg, pktsiz)) <= 0) {
637     timer_start = 0; /* clear timer */
638     if (errno == 0) {
639       b_errno = ENODATA;
640     } else {
641       b_errno = errno;
642     }
643     errors++;
644     Qmsg4(jcr_, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"), who_,
645           host_, port_, this->bstrerror());
646     nbytes = BNET_ERROR;
647     goto get_out;
648   }
649   timer_start = 0; /* clear timer */
650   in_msg_no++;
651   message_length = nbytes;
652   if (nbytes != pktsiz) {
653     b_errno = EIO;
654     errors++;
655     Qmsg5(jcr_, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
656           pktsiz, nbytes, who_, host_, port_);
657     nbytes = BNET_ERROR;
658     goto get_out;
659   }
660 
661   /*
662    * Always add a zero by to properly Terminate any string that was send to us.
663    * Note, we ensured above that the buffer is at least one byte longer than
664    * the message length.
665    */
666   msg[nbytes] = 0; /* Terminate in case it is a string */
667 
668   /*
669    * The following uses *lots* of resources so turn it on only for serious
670    * debugging.
671    */
672 
673 get_out:
674   if (mutex_) { mutex_->unlock(); }
675 
676   return nbytes; /* return actual length of message */
677 }
678 
GetPeer(char * buf,socklen_t buflen)679 int BareosSocketTCP::GetPeer(char* buf, socklen_t buflen)
680 {
681 #if !defined(HAVE_WIN32)
682   if (peer_addr.sin_family == 0) {
683     socklen_t salen = sizeof(peer_addr);
684     int rval = (getpeername)(fd_, (struct sockaddr*)&peer_addr, &salen);
685     if (rval < 0) return rval;
686   }
687   if (!inet_ntop(peer_addr.sin_family, &peer_addr.sin_addr, buf, buflen))
688     return -1;
689 
690   return 0;
691 #else
692   return -1;
693 #endif
694 }
695 
696 /*
697  * Set the network buffer size, suggested size is in size.
698  * Actual size obtained is returned in bs->message_length
699  *
700  * Returns: false on failure
701  *          true  on success
702  */
SetBufferSize(uint32_t size,int rw)703 bool BareosSocketTCP::SetBufferSize(uint32_t size, int rw)
704 {
705   uint32_t dbuf_size, start_size;
706 
707 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
708   int opt;
709 
710   opt = IPTOS_THROUGHPUT;
711   setsockopt(fd_, IPPROTO_IP, IP_TOS, (sockopt_val_t)&opt, sizeof(opt));
712 #endif
713 
714   if (size != 0) {
715     dbuf_size = size;
716   } else {
717     dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
718   }
719   start_size = dbuf_size;
720   if ((msg = ReallocPoolMemory(msg, dbuf_size + 100)) == NULL) {
721     Qmsg0(get_jcr(), M_FATAL, 0,
722           _("Could not malloc BareosSocket data buffer\n"));
723     return false;
724   }
725 
726   /*
727    * If user has not set the size, use the OS default -- i.e. do not
728    * try to set it.  This allows sys admins to set the size they
729    * want in the OS, and BAREOS will comply. See bug #1493
730    */
731   if (size == 0) {
732     message_length = dbuf_size;
733     return true;
734   }
735 
736   if (rw & BNET_SETBUF_READ) {
737     while ((dbuf_size > TAPE_BSIZE)
738            && (setsockopt(fd_, SOL_SOCKET, SO_RCVBUF, (sockopt_val_t)&dbuf_size,
739                           sizeof(dbuf_size))
740                < 0)) {
741       BErrNo be;
742       Qmsg1(get_jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.bstrerror());
743       dbuf_size -= TAPE_BSIZE;
744     }
745     Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
746     if (dbuf_size != start_size) {
747       Qmsg1(get_jcr(), M_WARNING, 0,
748             _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
749     }
750   }
751   if (size != 0) {
752     dbuf_size = size;
753   } else {
754     dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
755   }
756   start_size = dbuf_size;
757   if (rw & BNET_SETBUF_WRITE) {
758     while ((dbuf_size > TAPE_BSIZE)
759            && (setsockopt(fd_, SOL_SOCKET, SO_SNDBUF, (sockopt_val_t)&dbuf_size,
760                           sizeof(dbuf_size))
761                < 0)) {
762       BErrNo be;
763       Qmsg1(get_jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.bstrerror());
764       dbuf_size -= TAPE_BSIZE;
765     }
766     Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
767     if (dbuf_size != start_size) {
768       Qmsg1(get_jcr(), M_WARNING, 0,
769             _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
770     }
771   }
772 
773   message_length = dbuf_size;
774   return true;
775 }
776 
777 /*
778  * Set socket non-blocking
779  *
780  * Returns previous socket flag
781  */
SetNonblocking()782 int BareosSocketTCP::SetNonblocking()
783 {
784 #ifndef HAVE_WIN32
785   int oflags;
786 
787   /*
788    * Get current flags
789    */
790   if ((oflags = fcntl(fd_, F_GETFL, 0)) < 0) {
791     BErrNo be;
792     Qmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"),
793           be.bstrerror());
794   }
795 
796   /*
797    * Set O_NONBLOCK flag
798    */
799   if ((fcntl(fd_, F_SETFL, oflags | O_NONBLOCK)) < 0) {
800     BErrNo be;
801     Qmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"),
802           be.bstrerror());
803   }
804 
805   blocking_ = 0;
806   return oflags;
807 #else
808   int flags;
809   u_long ioctlArg = 1;
810 
811   flags = blocking_;
812   ioctlsocket(fd_, FIONBIO, &ioctlArg);
813   blocking_ = 0;
814 
815   return flags;
816 #endif
817 }
818 
819 /*
820  * Set socket blocking
821  *
822  * Returns previous socket flags
823  */
SetBlocking()824 int BareosSocketTCP::SetBlocking()
825 {
826 #ifndef HAVE_WIN32
827   int oflags;
828 
829   /*
830    * Get current flags
831    */
832   if ((oflags = fcntl(fd_, F_GETFL, 0)) < 0) {
833     BErrNo be;
834     Qmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"),
835           be.bstrerror());
836   }
837 
838   /*
839    * Set O_NONBLOCK flag
840    */
841   if ((fcntl(fd_, F_SETFL, oflags & ~O_NONBLOCK)) < 0) {
842     BErrNo be;
843     Qmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"),
844           be.bstrerror());
845   }
846 
847   blocking_ = 1;
848   return oflags;
849 #else
850   int flags;
851   u_long ioctlArg = 0;
852 
853   flags = blocking_;
854   ioctlsocket(fd_, FIONBIO, &ioctlArg);
855   blocking_ = 1;
856 
857   return flags;
858 #endif
859 }
860 
861 /*
862  * Restores socket flags
863  */
RestoreBlocking(int flags)864 void BareosSocketTCP::RestoreBlocking(int flags)
865 {
866 #ifndef HAVE_WIN32
867   if ((fcntl(fd_, F_SETFL, flags)) < 0) {
868     BErrNo be;
869     Qmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"),
870           be.bstrerror());
871   }
872 
873   blocking_ = (flags & O_NONBLOCK) ? true : false;
874 #else
875   u_long ioctlArg = flags;
876 
877   ioctlsocket(fd_, FIONBIO, &ioctlArg);
878   blocking_ = 1;
879 #endif
880 }
881 
882 /*
883  * Wait for a specified time for data to appear on
884  * the BareosSocket connection.
885  *
886  * Returns: 1 if data available
887  *          0 if timeout
888  *         -1 if error
889  */
WaitData(int sec,int usec)890 int BareosSocketTCP::WaitData(int sec, int usec)
891 {
892   int msec;
893 
894   msec = (sec * 1000) + (usec / 1000);
895   switch (WaitForReadableFd(fd_, msec, true)) {
896     case 0:
897       b_errno = 0;
898       return 0;
899     case -1:
900       b_errno = errno;
901       return -1; /* error return */
902     default:
903       b_errno = 0;
904       return 1;
905   }
906 }
907 
908 /*
909  * As above, but returns on interrupt
910  */
WaitDataIntr(int sec,int usec)911 int BareosSocketTCP::WaitDataIntr(int sec, int usec)
912 {
913   int msec;
914 
915   msec = (sec * 1000) + (usec / 1000);
916   switch (WaitForReadableFd(fd_, msec, false)) {
917     case 0:
918       b_errno = 0;
919       return 0;
920     case -1:
921       b_errno = errno;
922       return -1; /* error return */
923     default:
924       b_errno = 0;
925       return 1;
926   }
927 }
928 
929 #ifndef SHUT_RDWR
930 #  define SHUT_RDWR 2
931 #endif
932 
close()933 void BareosSocketTCP::close()
934 {
935   /* if not cloned */
936   ClearLocking();
937   CloseTlsConnectionAndFreeMemory();
938 
939   if (fd_ >= 0) {
940     if (!cloned_) {
941       if (IsTimedOut()) { shutdown(fd_, SHUT_RDWR); }
942     }
943     socketClose(fd_);
944     fd_ = -1;
945   }
946 }
947 
destroy()948 void BareosSocketTCP::destroy()
949 {
950   /* if this object is cloned
951    * some memory or file descriptors
952    * are duplicated not just copied */
953 
954   if (msg) { /* duplicated */
955     FreePoolMemory(msg);
956     msg = nullptr;
957   }
958   if (errmsg) { /* duplicated */
959     FreePoolMemory(errmsg);
960     errmsg = nullptr;
961   }
962   if (who_) { /* duplicated */
963     free(who_);
964     who_ = nullptr;
965   }
966   if (host_) { /* duplicated */
967     free(host_);
968     host_ = nullptr;
969   }
970   if (src_addr) { /* duplicated */
971     free(src_addr);
972     src_addr = nullptr;
973   }
974   if (fd_ >= 0) { /* duplicated */
975     socketClose(fd_);
976     fd_ = -1;
977   }
978   if (spool_fd_ >= 0) { /* duplicated */
979     socketClose(spool_fd_);
980     spool_fd_ = -1;
981   }
982 }
983 
984 /*
985  * Read a nbytes from the network.
986  * It is possible that the total bytes require in several
987  * read requests
988  */
read_nbytes(char * ptr,int32_t nbytes)989 int32_t BareosSocketTCP::read_nbytes(char* ptr, int32_t nbytes)
990 {
991   int32_t nleft, nread;
992 
993 #ifdef HAVE_TLS
994   if (tls_conn) { return (tls_conn->TlsBsockReadn(this, ptr, nbytes)); }
995 #endif /* HAVE_TLS */
996 
997   nleft = nbytes;
998   while (nleft > 0) {
999     errno = 0;
1000     nread = socketRead(fd_, ptr, nleft);
1001     if (IsTimedOut() || IsTerminated()) { return -1; }
1002 
1003 #ifdef HAVE_WIN32
1004     /*
1005      * For Windows, we must simulate Unix errno on a socket error in order to
1006      * handle errors correctly.
1007      */
1008     if (nread == SOCKET_ERROR) {
1009       DWORD err = WSAGetLastError();
1010       nread = -1;
1011       if (err == WSAEINTR) {
1012         errno = EINTR;
1013       } else if (err == WSAEWOULDBLOCK) {
1014         errno = EAGAIN;
1015       } else {
1016         errno = EIO; /* some other error */
1017       }
1018     }
1019 #endif
1020 
1021     if (nread == -1) {
1022       if (errno == EINTR) { continue; }
1023       if (errno == EAGAIN) {
1024         Bmicrosleep(0, 20000); /* try again in 20ms */
1025         continue;
1026       }
1027     }
1028 
1029     if (nread <= 0) { return -1; /* error, or EOF */ }
1030 
1031     nleft -= nread;
1032     ptr += nread;
1033     if (UseBwlimit()) { ControlBwlimit(nread); }
1034   }
1035 
1036   return nbytes - nleft; /* return >= 0 */
1037 }
1038 
1039 /*
1040  * Write nbytes to the network.
1041  * It may require several writes.
1042  */
write_nbytes(char * ptr,int32_t nbytes)1043 int32_t BareosSocketTCP::write_nbytes(char* ptr, int32_t nbytes)
1044 {
1045   int32_t nleft, nwritten;
1046 
1047   if (IsSpooling()) {
1048     nwritten = write(spool_fd_, ptr, nbytes);
1049     if (nwritten != nbytes) {
1050       BErrNo be;
1051       b_errno = errno;
1052       Qmsg1(jcr(), M_FATAL, 0, _("Attr spool write error. ERR=%s\n"),
1053             be.bstrerror());
1054       Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
1055       errno = b_errno;
1056       return -1;
1057     }
1058     return nbytes;
1059   }
1060 
1061   if (IsBnetDumpEnabled()) {
1062     bnet_dump_->DumpMessageAndStacktraceToFile(ptr, nbytes);
1063   }
1064 
1065 #ifdef HAVE_TLS
1066   if (tls_conn) { return (tls_conn->TlsBsockWriten(this, ptr, nbytes)); }
1067 #endif /* HAVE_TLS */
1068 
1069   nleft = nbytes;
1070   while (nleft > 0) {
1071     do {
1072       errno = 0;
1073       nwritten = socketWrite(fd_, ptr, nleft);
1074       if (IsTimedOut() || IsTerminated()) { return -1; }
1075 
1076 #ifdef HAVE_WIN32
1077       /*
1078        * For Windows, we must simulate Unix errno on a socket
1079        *  error in order to handle errors correctly.
1080        */
1081       if (nwritten == SOCKET_ERROR) {
1082         DWORD err = WSAGetLastError();
1083         nwritten = -1;
1084         if (err == WSAEINTR) {
1085           errno = EINTR;
1086         } else if (err == WSAEWOULDBLOCK) {
1087           errno = EAGAIN;
1088         } else {
1089           errno = EIO; /* some other error */
1090         }
1091       }
1092 #endif
1093 
1094     } while (nwritten == -1 && errno == EINTR);
1095 
1096     /*
1097      * If connection is non-blocking, we will get EAGAIN, so
1098      * use select()/poll() to keep from consuming all
1099      * the CPU and try again.
1100      */
1101     if (nwritten == -1 && errno == EAGAIN) {
1102       WaitForWritableFd(fd_, 1, false);
1103       continue;
1104     }
1105 
1106     if (nwritten <= 0) { return -1; /* error */ }
1107 
1108     nleft -= nwritten;
1109     ptr += nwritten;
1110     if (UseBwlimit()) { ControlBwlimit(nwritten); }
1111   }
1112 
1113   return nbytes - nleft;
1114 }
1115 
ConnectionReceivedTerminateSignal()1116 bool BareosSocketTCP::ConnectionReceivedTerminateSignal()
1117 {
1118   int32_t signal;
1119   SetNonblocking();
1120   bool terminated = false;
1121   if (::recv(fd_, (char*)&signal, 4, MSG_PEEK) == 4) {
1122     signal = ntohl(signal);
1123     if (signal == BNET_TERMINATE) {
1124       SetTerminated();
1125       terminated = true;
1126     }
1127   }
1128   SetBlocking();
1129   return terminated;
1130 }
1131