1. Find and fix the memory leak (most likely in address_conf.c)
in address_conf there was no memory leak-:) the parser calls my init_default_addresses
but also resets the datastructurs by memset so allocated resource will be lost.
I added the pass number to init_defaults so that i could call my init_default only once
per server.
2. Find some why to have smartalloc work correctly with new.
*Please* note, you cannot simply put everything on SMARTALLOC --
this will not work because some of the delete's *must* de-allocate
all the items in the list. I.e. by default, my lists own the
list items.
There was a missing brace
in the use of my new operator to write new(fname, line) Type in the define.
And also there was some operator definitions in dlist,alist,htable which causes
that trouble.
I only added the SMARTALLOC to all classes these are generated by new and removed
by delete.
3. I believe I've fixed the byte order problem by modifying get_port().
However, if you turn on the debug statement at the top of
init_bnet() src/lib/bnet.c:917 by setting the 100 to 000, you will
see that the host address is not correct in all cases.
Kern and I decided to add
get_port_net_order
get_port_host_order
get_first_port_net_order
get_first_port_host_order
to the code.
4. Eliminate the use of inet_addr() -- it is deprecated.
Done
5. Check the SetIP command in src/dir/fd_cmds.c
fixed mixup of sockaddr and in_addr
6. There is too much #ifdefing in the code to deal with IPv4 and IPv6
I don't mind it in bnet.c and bnet_server.c (too much), but we should
try to eliminate it elsewhere.
I cleaned it up.
Is this too much yes it is but, we can't reach the heaven in one day-:)
./lib/address_conf.c:#ifdef HAVE_IPV6
./lib/address_conf.c:#ifdef HAVE_IPV6
./lib/address_conf.c:#ifdef HAVE_IPV6
./lib/address_conf.c:#ifdef HAVE_IPV6
./lib/address_conf.c:#ifdef HAVE_IPV6
./lib/address_conf.c:#ifdef HAVE_IPV6
./lib/address_conf.c:#ifdef HAVE_IPV6
./lib/address_conf.c:#ifdef HAVE_IPV6
./lib/address_conf.c:#ifdef HAVE_IPV6
./lib/address_conf.c:#ifdef HAVE_IPV6
./lib/address_conf.c:#if defined(HAVE_INET_NTOP) && defined(HAVE_IPV6)
./lib/address_conf.c:#ifdef HAVE_IPV6
./lib/address_conf.c:#ifdef HAVE_INET_NTOP
./lib/address_conf.h:#ifdef HAVE_IPV6
./lib/address_conf.h:#ifdef HAVE_IPV6
./lib/address_conf.h:#ifdef HAVE_IPV6
./lib/bnet.c:#ifdef HAVE_IPV6
./lib/bnet.c:#ifdef HAVE_IPV6
./lib/bnet.c:#ifdef HAVE_IPV6
./lib/bnet.c:#ifdef HAVE_IPV6
./lib/bnet.c:#ifdef HAVE_IPV6
./lib/bnet_server.c:#ifndef HAVE_INET_NTOP
./lib/bnet_server.c:#ifdef HAVE_INET_NTOP
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1517
91ce42f0-d328-0410-95d8-
f526ca767f89
}
/* Create pid must come after we are a daemon -- so we have our final pid */
- create_pid_file(director->pid_directory, "bacula-dir", get_first_port(director->DIRaddrs));
- read_state_file(director->working_directory, "bacula-dir", get_first_port(director->DIRaddrs));
+ create_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
+ read_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
drop(uid, gid); /* reduce priveleges if requested */
exit(1);
}
already_here = TRUE;
- write_state_file(director->working_directory, "bacula-dir", get_first_port(director->DIRaddrs));
- delete_pid_file(director->pid_directory, "bacula-dir", get_first_port(director->DIRaddrs));
+ write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
+ delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
// signal(SIGCHLD, SIG_IGN); /* don't worry about children now */
term_scheduler();
term_job_server();
token = lex_get_token(lc, T_NAME);
if (pass == 1) {
if (((alist **)item->value)[item->code] == NULL) {
- ((alist **)item->value)[item->code] = new alist(10, owned_by_alist);
+ ((alist **)item->value)[item->code] = New(alist(10, owned_by_alist));
// Dmsg1(900, "Defined new ACL alist at %d\n", item->code);
}
((alist **)item->value)[item->code]->append(bstrdup(lc->str));
static int setip_cmd(UAContext *ua, const char *cmd)
{
CLIENT *client;
- char mybuf[1024];
- char *buf = mybuf;
+ char buf[1024];
if (!ua->cons || !acl_access_ok(ua, Client_ACL, ua->cons->hdr.name)) {
bsendmsg(ua, _("Illegal command from this console.\n"));
return 1;
if (client->address) {
free(client->address);
}
-#ifdef HAVE_INET_NTOP
- inet_ntop(ua->UA_sock->client_addr.sa_family,
- &(ua->UA_sock->client_addr), buf,
- ua->UA_sock->client_addr.sa_family == AF_INET ?
- sizeof(sockaddr_in) : sizeof(sockaddr_in6));
-#else
- buf = inet_ntoa(((struct sockaddr_in *)&(ua->UA_sock->client_addr))->sin_addr);
-#endif
-
+ /* MA Bug 6 remove ifdef */
+ sockaddr_to_ascii(&(ua->UA_sock->client_addr), buf, sizeof(buf));
client->address = bstrdup(buf);
bsendmsg(ua, _("Client \"%s\" address set to %s\n"),
client->hdr.name, client->address);
}
/* Maximum 1 daemon at a time */
- create_pid_file(me->pid_directory, "bacula-fd", get_first_port(me->FDaddrs));
- read_state_file(me->working_directory, "bacula-fd", get_first_port(me->FDaddrs));
+ create_pid_file(me->pid_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
+ read_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
drop(uid, gid);
int port = -1;
socklen_t client_addr_len = sizeof(client_addr);
if (getsockname(0, &client_addr, &client_addr_len) == 0) {
- if (client_addr.sa_family == AF_INET) {
- port = ((struct sockaddr_in*)&client_addr)->sin_port;
- }
-#ifdef HAVE_IPV6
- else if (client_addr.sa_family == AF_INET6) {
- port = ((struct sockaddr_in6*)&client_addr)->sin6_port;
- }
-#endif
+ /* MA BUG 6 remove ifdefs */
+ port = sockaddr_get_port_net_order(&client_addr);
}
BSOCK *bs = init_bsock(NULL, 0, "client", "unknown client", port, &client_addr);
handle_client_request((void *)bs);
/* Become server, and handle requests */
IPADDR *p;
foreach_dlist(p, me->FDaddrs) {
- Dmsg1(10, "filed: listening on port %d\n", ntohs(p->get_port()));
+ Dmsg1(10, "filed: listening on port %d\n", p->get_port_host_order());
}
bnet_thread_server(me->FDaddrs, me->MaxConcurrentJobs, &dir_workq, handle_client_request);
}
void terminate_filed(int sig)
{
bnet_stop_thread_server(server_tid);
- write_state_file(me->working_directory, "bacula-fd", get_first_port(me->FDaddrs));
- delete_pid_file(me->pid_directory, "bacula-fd", get_first_port(me->FDaddrs));
+ write_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
+ delete_pid_file(me->pid_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
if (configfile != NULL) {
free(configfile);
}
break;
case R_CLIENT:
sendit(sock, "Client: name=%s FDport=%d\n", reshdr->name,
- get_first_port(res->res_client.FDaddrs));
+ get_first_port_host_order(res->res_client.FDaddrs));
break;
case R_MSGS:
sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name);
if (res->res_dir.hdr.desc) {
free(res->res_dir.hdr.desc);
}
-
switch (type) {
case R_DIRECTOR:
if (res->res_dir.password) {
return type;
}
-unsigned short IPADDR::get_port() const
+unsigned short IPADDR::get_port_net_order() const
{
unsigned short port = 0;
if (saddr->sa_family == AF_INET) {
return port;
}
-void IPADDR::set_port(unsigned short port)
+void IPADDR::set_port_net(unsigned short port)
{
if (saddr->sa_family == AF_INET) {
saddr4->sin_port = port;
char tmp[1024];
bsnprintf(buf, blen, "host[%s:%s:%hu] ",
get_family() == AF_INET ? "ipv4" : "ipv6",
- get_address(tmp, sizeof(tmp) - 1), ntohs(get_port()));
+ get_address(tmp, sizeof(tmp) - 1), get_port_host_order());
return buf;
}
return ((IPADDR *)(addrs->first()))->get_address(outputbuf, outlen);
}
-int get_first_port(dlist * addrs)
+int get_first_port_net_order(dlist * addrs)
{
- return ntohs(((IPADDR *)(addrs->first()))->get_port());
+ return ((IPADDR *)(addrs->first()))->get_port_net_order();
+}
+
+int get_first_port_host_order(dlist * addrs)
+{
+ return ((IPADDR *)(addrs->first()))->get_port_host_order();
}
static int skip_to_next_not_eol(LEX * lc)
if (addrs->size()) {
addr = (IPADDR *)addrs->first();
} else {
- addr = new IPADDR(family);
+ addr = New(IPADDR(family));
addr->set_type(type);
- addr->set_port(defaultport);
+ addr->set_port_net(defaultport);
addr->set_addr_any();
addrs->append(addr);
}
if (intype == IPADDR::R_SINGLE_PORT) {
- addr->set_port(port);
+ addr->set_port_net(port);
}
if (intype == IPADDR::R_SINGLE_ADDR) {
addr->copy_addr((IPADDR *) (hostaddrs->first()));
goto skip; /* no price */
}
}
- clone = new IPADDR(*iaddr);
+ clone = New(IPADDR(*iaddr));
clone->set_type(type);
- clone->set_port(port);
+ clone->set_port_net(port);
addrs->append(clone);
skip:
continue;
char port_str[128];
int family = 0;
+
+
/*
* = { [[ip|ipv4|ipv6] = { [[addr|port] = [^ ]+[\n;]+] }]+ }
* or my tests
}
char *errstr;
- if (!add_address((dlist **)(item->value), IPADDR::R_MULTIPLE,
- htons(item->default_value), family, hostname_str, port_str, &errstr)) {
- scan_err3(lc, _("Can't add hostname(%s) and port(%s) to addrlist (%s)"),
+ if (pass == 1 && !add_address((dlist **)(item->value), IPADDR::R_MULTIPLE,
+ htons(item->default_value), family, hostname_str, port_str, &errstr)) {
+ scan_err3(lc, _("Can't add hostname(%s) and port(%s) to addrlist (%s)"),
hostname_str, port_str, errstr);
- free(errstr);
- }
+ free(errstr);
+ }
token = skip_to_next_not_eol(lc);
} while ((token == T_IDENTIFIER || token == T_UNQUOTED_STRING));
if (token != T_EOB) {
void store_addresses_address(LEX * lc, RES_ITEM * item, int index, int pass)
{
+
int token = lex_get_token(lc, T_ALL);
if (!(token == T_UNQUOTED_STRING || token == T_NUMBER || token == T_IDENTIFIER)) {
scan_err1(lc, _("Expected a hostname or ipnummer, got: %s"), lc->str);
}
char *errstr;
- if (!add_address((dlist **) (item->value), IPADDR::R_SINGLE_ADDR,
+ if (pass == 1 && !add_address((dlist **) (item->value), IPADDR::R_SINGLE_ADDR,
htons(item->default_value), AF_INET, lc->str, 0, &errstr)) {
scan_err2(lc, _("can't add port (%s) to (%s)"), lc->str, errstr);
free(errstr);
scan_err1(lc, _("Expected a port nummer or string, got: %s"), lc->str);
}
char *errstr;
- if (!add_address((dlist **)(item->value), IPADDR::R_SINGLE_PORT,
+ if (pass == 1 && !add_address((dlist **)(item->value), IPADDR::R_SINGLE_PORT,
htons(item->default_value), AF_INET, 0, lc->str, &errstr)) {
scan_err2(lc, _("can't add port (%s) to (%s)"), lc->str, errstr);
free(errstr);
}
delete addrs;
}
+
+int sockaddr_get_port_net_order(const struct sockaddr *client_addr)
+{
+ /* MA BUG 6 remove ifdefs */
+ if (client_addr->sa_family == AF_INET) {
+ return ((struct sockaddr_in *)client_addr)->sin_port;
+ }
+ else {
+ return ((struct sockaddr_in6 *)client_addr)->sin6_port;
+ }
+ return -1;
+}
+
+int sockaddr_to_ascii(const struct sockaddr *sa, char *buf, int len)
+{
+#ifdef HAVE_INET_NTOP
+ /* MA Bug 5 the problem was that i mixed up sockaddr and in_addr */
+ inet_ntop(sa->sa_family,
+ sa->sa_family == AF_INET ?
+ (void*)&(((struct sockaddr_in*)sa)->sin_addr) :
+ (void*)&(((struct sockaddr_in6*)sa)->sin6_addr),
+ buf,
+ sa->sa_family == AF_INET ? sizeof(in_addr) : sizeof(in6_addr));
+#else
+ bstrncpy(buf, inet_ntoa(((struct sockaddr_in *)sa)->sin_addr), len);
+#endif
+ return 1;
+}
+
*/
-class IPADDR {
+class IPADDR : public SMARTALLOC {
public:
typedef enum { R_SINGLE, R_SINGLE_PORT, R_SINGLE_ADDR, R_MULTIPLE,
R_DEFAULT, R_EMPTY
public:
void set_type(i_type o);
i_type get_type() const;
- unsigned short get_port() const;
- void set_port(unsigned short port);
+ unsigned short get_port_net_order() const;
+ unsigned short get_port_host_order() const
+ {
+ return ntohs(get_port_net_order());
+ }
+ void set_port_net(unsigned short port);
int get_family() const;
struct sockaddr *get_sockaddr();
int get_sockaddr_len();
extern void init_default_addresses(dlist ** addr, int port);
extern const char *get_first_address(dlist * addrs, char *outputbuf, int outlen);
-extern int get_first_port(dlist * addrs);
+extern int get_first_port_net_order(dlist * addrs);
+extern int get_first_port_host_order(dlist * addrs);
extern const char *build_addresses_str(dlist *addrs, char *buf, int blen);
+
+extern int sockaddr_get_port_net_order(const struct sockaddr *sa);
+extern int sockaddr_to_ascii(const struct sockaddr *sa, char *buf, int len);
* Array list -- much like a simplified STL vector
* array of pointers to inserted items
*/
-class alist {
+class alist : public SMARTALLOC {
void **items;
int num_items;
int max_items;
int size() const;
void destroy();
void grow(int num);
- void * operator new(size_t);
- void operator delete(void *);
};
inline void * alist::operator [](int index) const {
num_grow = num;
}
-inline void * alist::operator new(size_t)
-{
- return malloc(sizeof(alist));
-}
-
-inline void alist::operator delete(void *item)
-{
- ((alist *)item)->destroy();
- free(item);
-}
* must to a GetLastError() to get the error code for formatting.
* If bit 29 in berrno_ is not set, then it is a Unix errno.
*/
-class berrno {
+class berrno : public SMARTALLOC {
POOLMEM *buf_;
int berrno_;
public:
static IPADDR *add_any(int family)
{
- IPADDR *addr = new IPADDR(family);
+ IPADDR *addr = New(IPADDR(family));
addr->set_type(IPADDR::R_MULTIPLE);
addr->set_addr_any();
return addr;
} else {
char **p;
for (p = hp->h_addr_list; *p != 0; p++) {
- IPADDR *addr = new IPADDR(hp->h_addrtype);
+ IPADDR *addr = New(IPADDR(hp->h_addrtype));
addr->set_type(IPADDR::R_MULTIPLE);
if (addr->get_family() == AF_INET) {
addr->set_addr4((struct in_addr*)*p);
struct in6_addr inaddr6;
#endif
- dlist *addr_list = new dlist(addr, &addr->link);
+ dlist *addr_list = New(dlist(addr, &addr->link));
if (!host || host[0] == '\0') {
if (family != 0) {
addr_list->append(add_any(family));
addr_list->append(add_any(AF_INET6));
#endif
}
- } else if ((inaddr.s_addr = inet_addr(host)) != INADDR_NONE) {
- addr = new IPADDR(AF_INET);
+ } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
+ addr = New(IPADDR(AF_INET));
addr->set_type(IPADDR::R_MULTIPLE);
addr->set_addr4(&inaddr);
addr_list->append(addr);
} else
#ifdef HAVE_IPV6
if (inet_pton(AF_INET6, host, &inaddr6) > 1) {
- addr = new IPADDR(AF_INET6);
+ addr = New(IPADDR(AF_INET6));
addr->set_type(IPADDR::R_MULTIPLE);
addr->set_addr6(&inaddr6);
addr_list->append(addr);
}
foreach_dlist(ipaddr, addr_list) {
- ipaddr->set_port(htons(port));
+ ipaddr->set_port_net(htons(port));
char allbuf[256 * 10];
char curbuf[256];
Dmsg2(100, "Current %sAll %s\n",
save_errno = errno;
*fatal = 1;
Pmsg3(000, "Socket open error. proto=%d port=%d. ERR=%s\n",
- ipaddr->get_family(), ipaddr->get_port(), be.strerror());
+ ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror());
continue;
}
/*
foreach_dlist(p, addrs) {
/* Allocate on stack frame -- no need to free */
fd_ptr = (s_sockfd *)alloca(sizeof(s_sockfd));
- fd_ptr->port = p->get_port();
+ fd_ptr->port = p->get_port_net_order();
/*
* Open a TCP socket
*/
if (tlog <= 0) {
tlog = 2 * 60; /* Complain every 2 minutes */
Emsg2(M_WARNING, 0, _("Cannot bind port %d: ERR=%s. Retrying ...\n"),
- fd_ptr->port, be.strerror());
+ ntohs(fd_ptr->port), be.strerror());
}
bmicrosleep(5, 0);
if (--tmax <= 0) {
- Emsg2(M_ABORT, 0, _("Cannot bind port %d: ERR=%s.\n"), fd_ptr->port,
+ Emsg2(M_ABORT, 0, _("Cannot bind port %d: ERR=%s.\n"), ntohs(fd_ptr->port),
be.strerror());
}
}
*/
#define M_ABORT 1
-#undef New
-#define New(type) new type
/* In case you want to specifically specify the offset to the link */
#define OFFSET(item, link) ((char *)(link) - (char *)(item))
void *prev;
};
-class dlist {
+class dlist : public SMARTALLOC {
void *head;
void *tail;
int16_t loffset;
void destroy();
void *first() const;
void *last() const;
- void * operator new(size_t);
- void operator delete(void *);
};
-dlist *new_dlist();
-dlist *new_dlist(void *item, dlink *link);
-
/*
* This allows us to do explicit initialization,
}
-inline void * dlist::operator new(size_t)
-{
- return malloc(sizeof(dlist));
-}
-
-inline void dlist::operator delete(void *item)
-{
- ((dlist *)item)->destroy();
- free(item);
-}
-
inline void * dlist::first() const
{
uint32_t hash; /* hash for this key */
};
-class htable {
+class htable : public SMARTALLOC {
hlink **table; /* hash table */
int loffset; /* link offset in item */
uint32_t num_items; /* current number of items */
void destroy();
void stats(); /* print stats about the table */
uint32_t size(); /* return size of table */
- void * operator new(size_t);
- void operator delete(void *);
};
* Initialize the static structure to zeros, then
* apply all the default values.
*/
-void init_resource(int type, RES_ITEM *items)
+void init_resource(int type, RES_ITEM *items, int pass)
{
int i;
int rindex = type - r_first;
*(uint64_t *)(items[i].value) = (uint64_t)items[i].default_value;
} else if (items[i].handler == store_time) {
*(utime_t *)(items[i].value) = (utime_t)items[i].default_value;
- } else if (items[i].handler == store_addresses) {
+ } else if (pass == 1 && items[i].handler == store_addresses) {
init_default_addresses((dlist**)items[i].value, items[i].default_value);
}
}
state = p_resource;
items = resources[i].items;
res_type = resources[i].rcode;
- init_resource(res_type, items);
+ init_resource(res_type, items, pass);
break;
}
if (state == p_none) {
#ifdef SMARTALLOC
-#define New(type) new(__FILE__, __LINE__ type
+#define New(type) new(__FILE__, __LINE__) type /* BUG 2 brace is missing */
#undef SMARTALLOC
#define SMARTALLOC SMARTALLOC
#else
-
#define New(type) new type
class SMARTALLOC
}
dev->fd = -1;
- dev->attached_dcrs = new dlist(dcr, &dcr->dev_link);
+ dev->attached_dcrs = New(dlist(dcr, &dcr->dev_link));
Dmsg2(29, "init_dev: tape=%d dev_name=%s\n", dev_is_tape(dev), dev->dev_name);
return dev;
dlist *recs; /* linked list of rec packets open */
block = new_block(dev);
- recs = new dlist(rec, &rec->link);
+ recs = New(dlist(rec, &rec->link));
position_to_first_file(jcr, dev);
for ( ; ok && !done; ) {
init_stack_dump(); /* pick up new pid */
}
- create_pid_file(me->pid_directory, "bacula-sd", get_first_port(me->sdaddrs));
- read_state_file(me->working_directory, "bacula-sd", get_first_port(me->sdaddrs));
+ create_pid_file(me->pid_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
+ read_state_file(me->working_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
drop(uid, gid);
bmicrosleep(0, 500000); /* give them 1/2 sec to clean up */
}
- write_state_file(me->working_directory, "bacula-sd", get_first_port(me->sdaddrs));
- delete_pid_file(me->pid_directory, "bacula-sd", get_first_port(me->sdaddrs));
+ write_state_file(me->working_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
+ delete_pid_file(me->pid_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
Dmsg1(200, "In terminate_stored() sig=%d\n", sig);
sendit(sock, "Storage: name=%s SDaddr=%s SDport=%d SDDport=%d HB=%s\n",
res->res_store.hdr.name,
NPRT(get_first_address(res->res_store.sdaddrs, buf, sizeof(buf))),
- get_first_port(res->res_store.sdaddrs),
- get_first_port(res->res_store.sddaddrs),
+ get_first_port_host_order(res->res_store.sdaddrs),
+ get_first_port_host_order(res->res_store.sddaddrs),
edit_utime(res->res_store.heartbeat_interval, buf, sizeof(buf)));
foreach_dlist(p, res->res_store.sdaddrs) {
sendit(sock, " SDaddr=%s SDport=%d\n",
- p->get_address(buf, sizeof(buf)), p->get_port());
+ p->get_address(buf, sizeof(buf)), p->get_port_host_order());
}
foreach_dlist(p, res->res_store.sddaddrs) {
sendit(sock, " SDDaddr=%s SDDport=%d\n",
- p->get_address(buf, sizeof(buf)), p->get_port());
+ p->get_address(buf, sizeof(buf)), p->get_port_host_order());
}
break;
case R_DEVICE: