Steve Polyack wrote:
Back to the drawing board.
I redid this patch to utilize two new config options: FDSourceAddress (bacula-fd.conf) and DirSourceAddress (bacula-dir.conf). When either of these are not set, the connection behavior does not change; bind(2) is not called and the kernel chooses the outgoing address. If you specify a source address Bacula will now choose that address to source connections from.

Here's an example for the Director and SD of where this becomes useful:
You have a Bacula director with several IP addresses available. 10.0.0.100 is a management address (firewall lets authorized users/IPs ssh to the server at this address), and 10.0.0.200 is the backup VIP. I have a storage daemon on anothermachine listening on a VIP 10.0.0.250. Previously, since 10.0.0.100 is the first address on the interface, when the Bacula director tries to connect, (whether it's to a storage daemon or file daemon) this connection will come from 10.0.0.100. This makes writing firewall rules in "default deny" environment unintuitive. Instead of just using the address the storage daemon and director are listening on ("bound" to) and writing firewall rules like:
allow $clients to $director on port 9102
allow $director to $storageDaemon on port 9103

I have to make exceptions to account for bacula connecting *from* the management address.
allow $clients to $director on port 9102
allow $director-Mgmt to $storageDaemon on port 9103

But now, I can tell the director to source it's connections from the same VIP it is listening on:
DirAddress = 10.0.0.200
DirSourceAddress 10.0.0.200
and corresponding "rules":
allow $clients to $director on port 9102
allow $director to $storageDaemon on port 9103
This preserves a 1:1 mapping of the Bacula services to the Bacula VIP.

Let me know if you need any further clarifications.  The patch is attached.
diff -ru bacula-2.4.4/src/dird/dird_conf.c 
bacula-2.4.4-patched/src/dird/dird_conf.c
--- bacula-2.4.4/src/dird/dird_conf.c   2008-06-19 15:44:34.000000000 -0400
+++ bacula-2.4.4-patched/src/dird/dird_conf.c   2009-03-27 08:02:05.000000000 
-0400
@@ -112,6 +112,7 @@
    {"dirport",     store_addresses_port,    ITEM(res_dir.DIRaddrs),  0, 
ITEM_DEFAULT, 9101},
    {"diraddress",  store_addresses_address, ITEM(res_dir.DIRaddrs),  0, 
ITEM_DEFAULT, 9101},
    {"diraddresses",store_addresses,         ITEM(res_dir.DIRaddrs),  0, 
ITEM_DEFAULT, 9101},
+   {"dirsourceaddress",store_addresses_address, ITEM(res_dir.DIRsrc_addr),  0, 
ITEM_DEFAULT, 0},
    {"queryfile",   store_dir,      ITEM(res_dir.query_file), 0, ITEM_REQUIRED, 
0},
    {"workingdirectory", store_dir, ITEM(res_dir.working_directory), 0, 
ITEM_REQUIRED, 0},
    {"scriptsdirectory", store_dir, ITEM(res_dir.scripts_directory), 0, 0, 0},
@@ -1001,6 +1002,9 @@
       if (res->res_dir.DIRaddrs) {
          free_addresses(res->res_dir.DIRaddrs);
       }
+      if (res->res_dir.DIRsrc_addr) {
+         free_addresses(res->res_dir.DIRsrc_addr);
+      }
       if (res->res_dir.tls_ctx) { 
          free_tls_context(res->res_dir.tls_ctx);
       }
diff -ru bacula-2.4.4/src/dird/dird_conf.h 
bacula-2.4.4-patched/src/dird/dird_conf.h
--- bacula-2.4.4/src/dird/dird_conf.h   2008-06-18 15:22:03.000000000 -0400
+++ bacula-2.4.4-patched/src/dird/dird_conf.h   2009-03-27 07:53:22.000000000 
-0400
@@ -106,6 +106,7 @@
 public:
    RES   hdr;
    dlist *DIRaddrs;
+   dlist *DIRsrc_addr;                /* address to source connections from */
    char *password;                    /* Password for UA access */
    char *query_file;                  /* SQL query file */
    char *working_directory;           /* WorkingDirectory */
diff -ru bacula-2.4.4/src/dird/fd_cmds.c bacula-2.4.4-patched/src/dird/fd_cmds.c
--- bacula-2.4.4/src/dird/fd_cmds.c     2008-08-15 12:58:28.000000000 -0400
+++ bacula-2.4.4-patched/src/dird/fd_cmds.c     2009-03-27 08:03:14.000000000 
-0400
@@ -79,7 +79,7 @@
 int connect_to_file_daemon(JCR *jcr, int retry_interval, int max_retry_time,
                            int verbose)
 {
-   BSOCK   *fd;
+   BSOCK   *fd = new_bsock();
    char ed1[30];
    utime_t heart_beat;
 
@@ -93,8 +93,11 @@
       char name[MAX_NAME_LENGTH + 100];
       bstrncpy(name, _("Client: "), sizeof(name));
       bstrncat(name, jcr->client->name(), sizeof(name));
-      fd = bnet_connect(jcr, retry_interval, max_retry_time, heart_beat,
-           name, jcr->client->address, NULL, jcr->client->FDport, verbose);
+      if (!fd->connect(jcr,retry_interval,max_retry_time, heart_beat, name, 
jcr->client->address,
+           NULL, jcr->client->FDport, verbose, director->DIRsrc_addr)) {
+         fd->destroy();
+         fd = NULL;
+      }
       if (fd == NULL) {
          set_jcr_job_status(jcr, JS_ErrorTerminated);
          return 0;
diff -ru bacula-2.4.4/src/dird/msgchan.c bacula-2.4.4-patched/src/dird/msgchan.c
--- bacula-2.4.4/src/dird/msgchan.c     2008-09-08 15:21:08.000000000 -0400
+++ bacula-2.4.4-patched/src/dird/msgchan.c     2009-03-27 08:03:02.000000000 
-0400
@@ -76,7 +76,7 @@
 bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
                               int max_retry_time, int verbose)
 {
-   BSOCK *sd;
+   BSOCK *sd = new_bsock();
    STORE *store;
    utime_t heart_beat;    
 
@@ -102,9 +102,11 @@
     */
    Dmsg2(100, "bnet_connect to Storage daemon %s:%d\n", store->address,
       store->SDport);
-   sd = bnet_connect(jcr, retry_interval, max_retry_time, heart_beat,
-          _("Storage daemon"), store->address,
-          NULL, store->SDport, verbose);
+      if (!sd->connect(jcr, retry_interval, max_retry_time, heart_beat, 
_("Storage daemon"),
+            store->address, NULL, store->SDport, verbose, 
director->DIRsrc_addr)) {
+         sd->destroy();
+         sd = NULL;
+      }
    if (sd == NULL) {
       return false;
    }
diff -ru bacula-2.4.4/src/filed/filed_conf.c 
bacula-2.4.4-patched/src/filed/filed_conf.c
--- bacula-2.4.4/src/filed/filed_conf.c 2008-06-18 15:22:03.000000000 -0400
+++ bacula-2.4.4-patched/src/filed/filed_conf.c 2009-03-27 07:41:45.000000000 
-0400
@@ -91,6 +91,7 @@
    {"fdport",      store_addresses_port,    ITEM(res_client.FDaddrs),  0, 
ITEM_DEFAULT, 9102},
    {"fdaddress",   store_addresses_address, ITEM(res_client.FDaddrs),  0, 
ITEM_DEFAULT, 9102},
    {"fdaddresses", store_addresses,         ITEM(res_client.FDaddrs),  0, 
ITEM_DEFAULT, 9102},
+   {"fdsourceaddress", store_addresses_address, ITEM(res_client.FDsrc_addr),  
0, ITEM_DEFAULT, 0},
 
    {"workingdirectory",  store_dir, ITEM(res_client.working_directory), 0, 
ITEM_REQUIRED, 0},
    {"piddirectory",  store_dir,     ITEM(res_client.pid_directory),     0, 
ITEM_REQUIRED, 0},
@@ -260,6 +261,9 @@
       if (res->res_client.FDaddrs) {
          free_addresses(res->res_client.FDaddrs);
       }
+      if (res->res_client.FDsrc_addr) {
+         free_addresses(res->res_client.FDaddrs);
+      }
 
       if (res->res_client.pki_keypair_file) { 
          free(res->res_client.pki_keypair_file);
diff -ru bacula-2.4.4/src/filed/filed_conf.h 
bacula-2.4.4-patched/src/filed/filed_conf.h
--- bacula-2.4.4/src/filed/filed_conf.h 2008-06-18 15:22:03.000000000 -0400
+++ bacula-2.4.4-patched/src/filed/filed_conf.h 2009-03-27 07:53:38.000000000 
-0400
@@ -75,6 +75,7 @@
 struct CLIENT {
    RES   hdr;
    dlist *FDaddrs;
+   dlist *FDsrc_addr;                 /* address to source connections from */
    char *working_directory;
    char *pid_directory;
    char *subsys_directory;
diff -ru bacula-2.4.4/src/filed/job.c bacula-2.4.4-patched/src/filed/job.c
--- bacula-2.4.4/src/filed/job.c        2008-06-30 08:56:49.000000000 -0400
+++ bacula-2.4.4-patched/src/filed/job.c        2009-03-27 07:50:12.000000000 
-0400
@@ -1292,7 +1292,7 @@
    int stored_port;                /* storage daemon port */
    int enable_ssl;                 /* enable ssl to sd */
    BSOCK *dir = jcr->dir_bsock;
-   BSOCK *sd;                         /* storage daemon bsock */
+   BSOCK *sd = new_bsock();                         /* storage daemon bsock */
 
    Dmsg1(100, "StorageCmd: %s", dir->msg);
    if (sscanf(dir->msg, storaddr, &jcr->stored_addr, &stored_port, 
&enable_ssl) != 3) {
@@ -1303,8 +1303,14 @@
    Dmsg3(110, "Open storage: %s:%d ssl=%d\n", jcr->stored_addr, stored_port, 
enable_ssl);
    /* Open command communications with Storage daemon */
    /* Try to connect for 1 hour at 10 second intervals */
-   sd = bnet_connect(jcr, 10, (int)me->SDConnectTimeout, 
me->heartbeat_interval,
-                      _("Storage daemon"), jcr->stored_addr, NULL, 
stored_port, 1);
+
+   if (!sd->connect(jcr, 10, (int)me->SDConnectTimeout, me->heartbeat_interval,
+                _("Storage daemon"), jcr->stored_addr, NULL, stored_port, 1, 
me->FDsrc_addr)) {
+     sd->destroy();
+     sd = NULL;
+   }
+
+
    if (sd == NULL) {
       Jmsg(jcr, M_FATAL, 0, _("Failed to connect to Storage daemon: %s:%d\n"),
           jcr->stored_addr, stored_port);
diff -ru bacula-2.4.4/src/lib/bnet.c bacula-2.4.4-patched/src/lib/bnet.c
--- bacula-2.4.4/src/lib/bnet.c 2008-07-19 11:50:38.000000000 -0400
+++ bacula-2.4.4-patched/src/lib/bnet.c 2009-03-17 10:13:04.000000000 -0400
@@ -523,7 +523,7 @@
 {
    BSOCK *bsock = new_bsock();
    if (!bsock->connect(jcr, retry_interval, max_retry_time, heart_beat,
-                       name, host, service, port, verbose)) {
+                       name, host, service, port, verbose, NULL)) {
        bsock->destroy();
        bsock = NULL;
    }
diff -ru bacula-2.4.4/src/lib/bsock.c bacula-2.4.4-patched/src/lib/bsock.c
--- bacula-2.4.4/src/lib/bsock.c        2008-07-19 11:50:38.000000000 -0400
+++ bacula-2.4.4-patched/src/lib/bsock.c        2009-03-27 09:54:06.000000000 
-0400
@@ -93,7 +93,7 @@
 bool BSOCK::connect(JCR * jcr, int retry_interval, utime_t max_retry_time,
                     utime_t heart_beat,
                     const char *name, char *host, char *service, int port,
-                    int verbose)
+                    int verbose, dlist *src_addrs)
 {
    bool ok = false;
    int i;
@@ -107,7 +107,7 @@
       tid = start_thread_timer(pthread_self(), (uint32_t)max_retry_time);
    }
    
-   for (i = 0; !open(jcr, name, host, service, port, heart_beat, &fatal);
+   for (i = 0; !open(jcr, name, host, service, port, heart_beat, &fatal, 
src_addrs);
         i -= retry_interval) {
       berrno be;
       if (fatal || (jcr && job_canceled(jcr))) {
@@ -162,11 +162,11 @@
  *
  */
 bool BSOCK::open(JCR *jcr, const char *name, char *host, char *service,
-            int port, utime_t heart_beat, int *fatal)
+            int port, utime_t heart_beat, int *fatal, dlist *src_addr_list)
 {
    int sockfd = -1;
    dlist *addr_list;
-   IPADDR *ipaddr;
+   IPADDR *ipaddr, *src_addr;
    bool connected = false;
    int turnon = 1;
    const char *errstr;
@@ -185,7 +185,7 @@
       *fatal = 1;
       return false;
    }
-
+ 
    foreach_dlist(ipaddr, addr_list) {
       ipaddr->set_port_net(htons(port));
       char allbuf[256 * 10];
@@ -202,6 +202,18 @@
             ipaddr->get_family(), ipaddr->get_port_host_order(), 
be.bstrerror());
          continue;
       }
+
+      if (src_addr_list) {
+         src_addr = (IPADDR *) src_addr_list->first();
+         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
        */
diff -ru bacula-2.4.4/src/lib/bsock.h bacula-2.4.4-patched/src/lib/bsock.h
--- bacula-2.4.4/src/lib/bsock.h        2008-07-22 10:48:21.000000000 -0400
+++ bacula-2.4.4-patched/src/lib/bsock.h        2009-03-17 10:12:26.000000000 
-0400
@@ -66,7 +66,7 @@
    void fin_init(JCR * jcr, int sockfd, const char *who, const char *host, int 
port,
                struct sockaddr *lclient_addr);
    bool open(JCR *jcr, const char *name, char *host, char *service,
-               int port, utime_t heart_beat, int *fatal);
+               int port, utime_t heart_beat, int *fatal, dlist* srcaddrs);
    
 public:
    uint64_t read_seqno;               /* read sequence number */
@@ -93,7 +93,7 @@
    void free_bsock();
    bool connect(JCR * jcr, int retry_interval, utime_t max_retry_time,
                 utime_t heart_beat, const char *name, char *host, 
-                char *service, int port, int verbose);
+                char *service, int port, int verbose, dlist *srcaddrs);
    int32_t recv();
    bool send();
    bool fsend(const char*, ...);
------------------------------------------------------------------------------
_______________________________________________
Bacula-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bacula-devel

Reply via email to