From 96be9d4715f40b6b9c378417f73ff80ac214dede Mon Sep 17 00:00:00 2001 From: Eric Bollengier Date: Tue, 26 May 2009 13:44:08 +0000 Subject: [PATCH] ebl Apply Steve Polyack patch to add DirSourceAddress and FDSourceAddress directives. That permits to choose the outgoing interface. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@8863 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/dird/dird_conf.c | 4 ++++ bacula/src/dird/dird_conf.h | 1 + bacula/src/dird/fd_cmds.c | 12 +++++++++--- bacula/src/dird/msgchan.c | 12 ++++++++---- bacula/src/filed/filed_conf.c | 4 ++++ bacula/src/filed/filed_conf.h | 1 + bacula/src/filed/job.c | 12 +++++++++--- bacula/src/lib/bnet.c | 3 +++ bacula/src/lib/bsock.c | 37 +++++++++++++++++++++++++++++++++++ bacula/src/lib/bsock.h | 2 ++ bacula/src/lib/lib.h | 2 +- bacula/technotes | 3 +++ 12 files changed, 82 insertions(+), 11 deletions(-) diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 3087c440d5..83c583618c 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -112,6 +112,7 @@ static RES_ITEM dir_items[] = { {"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}, {"plugindirectory", store_dir, ITEM(res_dir.plugin_directory), 0, 0, 0}, @@ -1079,6 +1080,9 @@ void free_resource(RES *sres, int type) 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 --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h index fea4ee029e..231dfabe5d 100644 --- a/bacula/src/dird/dird_conf.h +++ b/bacula/src/dird/dird_conf.h @@ -106,6 +106,7 @@ class DIRRES { 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 --git a/bacula/src/dird/fd_cmds.c b/bacula/src/dird/fd_cmds.c index 5badf778bf..6859a6e55f 100644 --- a/bacula/src/dird/fd_cmds.c +++ b/bacula/src/dird/fd_cmds.c @@ -80,7 +80,7 @@ extern int FDConnectTimeout; 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; @@ -94,8 +94,14 @@ int connect_to_file_daemon(JCR *jcr, int retry_interval, int max_retry_time, 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); + + fd->set_source_address(director->DIRsrc_addr); + if (!fd->connect(jcr,retry_interval,max_retry_time, heart_beat, name, jcr->client->address, + NULL, jcr->client->FDport, verbose)) { + fd->destroy(); + fd = NULL; + } + if (fd == NULL) { set_jcr_job_status(jcr, JS_ErrorTerminated); return 0; diff --git a/bacula/src/dird/msgchan.c b/bacula/src/dird/msgchan.c index 1955ccc093..1ccfb81c0c 100644 --- a/bacula/src/dird/msgchan.c +++ b/bacula/src/dird/msgchan.c @@ -76,7 +76,7 @@ extern "C" void *msg_thread(void *arg); 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,13 @@ bool connect_to_storage_daemon(JCR *jcr, int retry_interval, */ 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); + sd->set_source_address(director->DIRsrc_addr); + if (!sd->connect(jcr, retry_interval, max_retry_time, heart_beat, _("Storage daemon"), + store->address, NULL, store->SDport, verbose)) { + sd->destroy(); + sd = NULL; + } + if (sd == NULL) { return false; } diff --git a/bacula/src/filed/filed_conf.c b/bacula/src/filed/filed_conf.c index 7a07998759..b8470c39b3 100644 --- a/bacula/src/filed/filed_conf.c +++ b/bacula/src/filed/filed_conf.c @@ -91,6 +91,7 @@ static RES_ITEM cli_items[] = { {"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}, @@ -267,6 +268,9 @@ void free_resource(RES *sres, int type) if (res->res_client.FDaddrs) { free_addresses(res->res_client.FDaddrs); } + if (res->res_client.FDsrc_addr) { + free_addresses(res->res_client.FDsrc_addr); + } if (res->res_client.pki_keypair_file) { free(res->res_client.pki_keypair_file); diff --git a/bacula/src/filed/filed_conf.h b/bacula/src/filed/filed_conf.h index 3624950b0e..978c94a584 100644 --- a/bacula/src/filed/filed_conf.h +++ b/bacula/src/filed/filed_conf.h @@ -76,6 +76,7 @@ struct DIRRES { struct CLIENT { RES hdr; dlist *FDaddrs; + dlist *FDsrc_addr; /* address to source connections from */ char *working_directory; char *pid_directory; char *subsys_directory; diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index c85e5ad0b0..4d825499ee 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -1371,7 +1371,7 @@ static int storage_cmd(JCR *jcr) 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) { @@ -1382,8 +1382,14 @@ static int storage_cmd(JCR *jcr) 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); + + sd->set_source_address(me->FDsrc_addr); + if (!sd->connect(jcr, 10, (int)me->SDConnectTimeout, me->heartbeat_interval, + _("Storage daemon"), jcr->stored_addr, NULL, stored_port, 1)) { + 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 --git a/bacula/src/lib/bnet.c b/bacula/src/lib/bnet.c index 2e247eef23..ee2415db8d 100644 --- a/bacula/src/lib/bnet.c +++ b/bacula/src/lib/bnet.c @@ -702,6 +702,9 @@ BSOCK *dup_bsock(BSOCK *osock) if (osock->host()) { bsock->set_host(bstrdup(osock->host())); } + if (osock->src_addr) { + bsock->src_addr = New( IPADDR( *(osock->src_addr)) ); + } bsock->set_duped(); return bsock; } diff --git a/bacula/src/lib/bsock.c b/bacula/src/lib/bsock.c index 788c123726..a19a90b011 100644 --- a/bacula/src/lib/bsock.c +++ b/bacula/src/lib/bsock.c @@ -161,6 +161,26 @@ void BSOCK::fin_init(JCR * jcr, int sockfd, const char *who, const char *host, i set_jcr(jcr); } +/* + * Copy the address from the configuration dlist that gets passed in + */ +void BSOCK::set_source_address(dlist *src_addr_list) +{ + IPADDR *addr = NULL; + + // delete the object we already have, if it's allocated + if (src_addr) { + free( src_addr); + src_addr = NULL; + } + + if (src_addr_list) { + addr = (IPADDR*) src_addr_list->first(); + src_addr = New( IPADDR(*addr)); + } +} + + /* * Open a TCP connection to the server * Returns NULL @@ -208,6 +228,19 @@ bool BSOCK::open(JCR *jcr, const char *name, char *host, char *service, ipaddr->get_family(), ipaddr->get_port_host_order(), be.bstrerror()); continue; } + + /* Bind to the source address if it is set */ + if (src_addr) { + 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 */ @@ -885,6 +918,10 @@ void BSOCK::destroy() free(m_host); m_host = NULL; } + if (src_addr) { + free(src_addr); + src_addr = NULL; + } free(this); } diff --git a/bacula/src/lib/bsock.h b/bacula/src/lib/bsock.h index ccea240602..fca01157a4 100644 --- a/bacula/src/lib/bsock.h +++ b/bacula/src/lib/bsock.h @@ -89,6 +89,7 @@ public: FILE *m_spool_fd; /* spooling file */ struct sockaddr client_addr; /* client's IP address */ struct sockaddr_in peer_addr; /* peer's IP address */ + IPADDR *src_addr; /* IP address to source connections from */ /* methods -- in bsock.c */ void init(); @@ -116,6 +117,7 @@ public: TLS_CONTEXT *tls_ctx, char *msg, int msglen); bool set_locking(); /* in bsock.c */ void clear_locking(); /* in bsock.c */ + void set_source_address(dlist *src_addr_list); /* Inline functions */ void set_jcr(JCR *jcr) { m_jcr = jcr; }; diff --git a/bacula/src/lib/lib.h b/bacula/src/lib/lib.h index 07bc7e518e..09655c9a85 100644 --- a/bacula/src/lib/lib.h +++ b/bacula/src/lib/lib.h @@ -53,6 +53,7 @@ #include "lex.h" #include "parse_conf.h" #include "tls.h" +#include "address_conf.h" #include "bsock.h" #include "workq.h" #ifndef HAVE_FNMATCH @@ -67,7 +68,6 @@ #include "bpipe.h" #include "attr.h" #include "var.h" -#include "address_conf.h" #include "guid_to_name.h" #include "protos.h" diff --git a/bacula/technotes b/bacula/technotes index 6d7fc3c466..079fa21322 100644 --- a/bacula/technotes +++ b/bacula/technotes @@ -2,6 +2,9 @@ General: +26May09 +ebl Apply Steve Polyack patch to add DirSourceAddress and FDSourceAddress + directives. That permits to choose the outgoing interface. 25May09 mvw Allow acl and xattr to be explicitly enabled and fail the configure if we are asked to enable acl or xattr support and the OS doesn't support -- 2.39.5