summaryrefslogtreecommitdiff
path: root/openvpn/src
diff options
context:
space:
mode:
Diffstat (limited to 'openvpn/src')
-rw-r--r--openvpn/src/openvpn/buffer.c38
-rw-r--r--openvpn/src/openvpn/buffer.h28
-rw-r--r--openvpn/src/openvpn/init.c18
-rw-r--r--openvpn/src/openvpn/manage.c18
-rw-r--r--openvpn/src/openvpn/route.c2
-rw-r--r--openvpn/src/openvpn/socket.c55
6 files changed, 106 insertions, 53 deletions
diff --git a/openvpn/src/openvpn/buffer.c b/openvpn/src/openvpn/buffer.c
index fb3b52d1..36611415 100644
--- a/openvpn/src/openvpn/buffer.c
+++ b/openvpn/src/openvpn/buffer.c
@@ -372,6 +372,44 @@ x_gc_free (struct gc_arena *a)
}
/*
+ * Functions to handle special objects in gc_entries
+ */
+
+void
+x_gc_freespecial (struct gc_arena *a)
+{
+ struct gc_entry_special *e;
+ e = a->list_special;
+ a->list_special = NULL;
+
+ while (e != NULL)
+ {
+ struct gc_entry_special *next = e->next;
+ e->free_fnc (e->addr);
+ free(e);
+ e = next;
+ }
+}
+
+void gc_addspecial (void *addr, void (free_function)(void*), struct gc_arena *a)
+{
+ ASSERT(a);
+ struct gc_entry_special *e;
+#ifdef DMALLOC
+ e = (struct gc_entry_special *) openvpn_dmalloc (file, line, sizeof (struct gc_entry_special));
+#else
+ e = (struct gc_entry_special *) malloc (sizeof (struct gc_entry_special));
+#endif
+ check_malloc_return (e);
+ e->free_fnc = free_function;
+ e->addr = addr;
+
+ e->next = a->list_special;
+ a->list_special = e;
+}
+
+
+/*
* Transfer src arena to dest, resetting src to an empty arena.
*/
void
diff --git a/openvpn/src/openvpn/buffer.h b/openvpn/src/openvpn/buffer.h
index 93efb096..425d0eb6 100644
--- a/openvpn/src/openvpn/buffer.h
+++ b/openvpn/src/openvpn/buffer.h
@@ -91,6 +91,18 @@ struct gc_entry
* linked list. */
};
+/**
+ * Gargabe collection entry for a specially allocated structure that needs
+ * a custom free function to be freed like struct addrinfo
+ *
+ */
+struct gc_entry_special
+{
+ struct gc_entry_special *next;
+ void (*free_fnc)(void*);
+ void *addr;
+};
+
/**
* Garbage collection arena used to keep track of dynamically allocated
@@ -106,6 +118,7 @@ struct gc_arena
{
struct gc_entry *list; /**< First element of the linked list of
* \c gc_entry structures. */
+ struct gc_entry_special *list_special;
};
@@ -153,7 +166,6 @@ char *string_alloc_debug (const char *str, struct gc_arena *gc, const char *file
struct buffer string_alloc_buf_debug (const char *str, struct gc_arena *gc, const char *file, int line);
#else
-
struct buffer alloc_buf (size_t size);
struct buffer alloc_buf_gc (size_t size, struct gc_arena *gc); /* allocate buffer with garbage collection */
struct buffer clone_buf (const struct buffer* buf);
@@ -163,6 +175,9 @@ struct buffer string_alloc_buf (const char *str, struct gc_arena *gc);
#endif
+void gc_addspecial (void *addr, void (*free_function)(void*), struct gc_arena *a);
+
+
#ifdef BUF_INIT_TRACKING
#define buf_init(buf, offset) buf_init_debug (buf, offset, __FILE__, __LINE__)
bool buf_init_debug (struct buffer *buf, int offset, const char *file, int line);
@@ -172,6 +187,11 @@ bool buf_init_debug (struct buffer *buf, int offset, const char *file, int line)
/* inline functions */
+inline static void
+gc_freeaddrinfo_callback (void *addr)
+{
+ freeaddrinfo((struct addrinfo*) addr);
+}
static inline bool
buf_defined (const struct buffer *buf)
@@ -778,6 +798,7 @@ void character_class_debug (void);
void gc_transfer (struct gc_arena *dest, struct gc_arena *src);
void x_gc_free (struct gc_arena *a);
+void x_gc_freespecial (struct gc_arena *a);
static inline bool
gc_defined (struct gc_arena *a)
@@ -789,6 +810,7 @@ static inline void
gc_init (struct gc_arena *a)
{
a->list = NULL;
+ a->list_special = NULL;
}
static inline void
@@ -801,7 +823,7 @@ static inline struct gc_arena
gc_new (void)
{
struct gc_arena ret;
- ret.list = NULL;
+ gc_init (&ret);
return ret;
}
@@ -810,6 +832,8 @@ gc_free (struct gc_arena *a)
{
if (a->list)
x_gc_free (a);
+ if (a->list_special)
+ x_gc_freespecial(a);
}
static inline void
diff --git a/openvpn/src/openvpn/init.c b/openvpn/src/openvpn/init.c
index 5979e0bb..0f76b2cc 100644
--- a/openvpn/src/openvpn/init.c
+++ b/openvpn/src/openvpn/init.c
@@ -306,11 +306,10 @@ init_connection_list (struct context *c)
/*
* Clear the remote address list
*/
-static void clear_remote_addrlist (struct link_socket_addr *lsa, bool freeaddr)
+static void clear_remote_addrlist (struct link_socket_addr *lsa, bool free)
{
- if (lsa->remote_list && freeaddr) {
- freeaddrinfo(lsa->remote_list);
- }
+ if (lsa->remote_list && free)
+ freeaddrinfo(lsa->remote_list);
lsa->remote_list = NULL;
lsa->current_remote = NULL;
}
@@ -349,11 +348,15 @@ next_connection_entry (struct context *c)
* remote existed
*/
if (!c->options.persist_remote_ip)
- clear_remote_addrlist (&c->c1.link_socket_addr, !c->options.resolve_in_advance);
+ {
+ /* close_instance should have cleared the addrinfo objects */
+ ASSERT (c->c1.link_socket_addr.current_remote == NULL);
+ ASSERT (c->c1.link_socket_addr.remote_list == NULL);
+ }
else
c->c1.link_socket_addr.current_remote =
c->c1.link_socket_addr.remote_list;
-
+
/*
* Increase the number of connection attempts
* If this is connect-retry-max * size(l)
@@ -2920,7 +2923,8 @@ do_close_link_socket (struct context *c)
if (!(c->sig->signal_received == SIGUSR1 && c->options.persist_local_ip)) {
if (c->c1.link_socket_addr.bind_local && !c->options.resolve_in_advance)
- freeaddrinfo(c->c1.link_socket_addr.bind_local);
+ freeaddrinfo(c->c1.link_socket_addr.bind_local);
+
c->c1.link_socket_addr.bind_local=NULL;
}
}
diff --git a/openvpn/src/openvpn/manage.c b/openvpn/src/openvpn/manage.c
index 352021bd..06965ad2 100644
--- a/openvpn/src/openvpn/manage.c
+++ b/openvpn/src/openvpn/manage.c
@@ -1568,9 +1568,9 @@ man_listen (struct management *man)
else
#endif
{
- man->connection.sd_top = create_socket_tcp (AF_INET);
+ man->connection.sd_top = create_socket_tcp (man->settings.local->ai_family);
socket_bind (man->connection.sd_top, man->settings.local,
- AF_INET, "MANAGEMENT", true);
+ man->settings.local->ai_family, "MANAGEMENT", false);
}
/*
@@ -2148,8 +2148,14 @@ man_settings_init (struct man_settings *ms,
}
else
{
- int status = openvpn_getaddrinfo(GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL,
- addr, port, 0, NULL, AF_INET, &ms->local);
+ int status;
+ int resolve_flags = GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL;
+
+ if (! (flags & MF_CONNECT_AS_CLIENT))
+ resolve_flags |= GETADDR_PASSIVE;
+
+ status = openvpn_getaddrinfo (resolve_flags, addr, port, 0,
+ NULL, AF_UNSPEC, &ms->local);
ASSERT(status==0);
}
}
@@ -2176,6 +2182,8 @@ man_settings_init (struct man_settings *ms,
static void
man_settings_close (struct man_settings *ms)
{
+ if (ms->local)
+ freeaddrinfo(ms->local);
free (ms->write_peer_info_file);
CLEAR (*ms);
}
@@ -2613,7 +2621,7 @@ management_post_tunnel_open (struct management *man, const in_addr_t tun_local_i
int ret;
ia.s_addr = htonl(tun_local_ip);
- ret = openvpn_getaddrinfo(0, inet_ntoa(ia), NULL, 0, NULL,
+ ret = openvpn_getaddrinfo(GETADDR_PASSIVE, inet_ntoa(ia), NULL, 0, NULL,
AF_INET, &man->settings.local);
ASSERT (ret==0);
man_connection_init (man);
diff --git a/openvpn/src/openvpn/route.c b/openvpn/src/openvpn/route.c
index f051dd3c..81ffa876 100644
--- a/openvpn/src/openvpn/route.c
+++ b/openvpn/src/openvpn/route.c
@@ -659,6 +659,7 @@ init_route_list (struct route_list *rl,
else
{
struct addrinfo* curele;
+ gc_addspecial(netlist, &gc_freeaddrinfo_callback, &gc);
for (curele = netlist; curele; curele = curele->ai_next)
{
if (j < rl->capacity)
@@ -675,7 +676,6 @@ init_route_list (struct route_list *rl,
}
}
}
- freeaddrinfo(netlist);
}
}
rl->n = j;
diff --git a/openvpn/src/openvpn/socket.c b/openvpn/src/openvpn/socket.c
index 05ae9e91..26ef14c3 100644
--- a/openvpn/src/openvpn/socket.c
+++ b/openvpn/src/openvpn/socket.c
@@ -146,30 +146,33 @@ do_preresolve(struct context *c)
if (! ce->preresolved_remote)
{
- status = openvpn_getaddrinfo (flags, remote, ce->remote_port,
- c->options.resolve_retry_seconds, NULL,
- ce->af, &ce->preresolved_remote);
+ status = openvpn_getaddrinfo (flags, remote, ce->remote_port,
+ c->options.resolve_retry_seconds, NULL,
+ ce->af, &ce->preresolved_remote);
- if (status != 0)
- goto err;
+ if (status != 0)
+ goto err;
+ gc_addspecial (ce->preresolved_remote, &gc_freeaddrinfo_callback, &c->gc);
}
flags |= GETADDR_PASSIVE;
- if (ce->bind_local && !ce->preresolved_local)
- {
- status = openvpn_getaddrinfo (flags, ce->local, ce->local_port,
- c->options.resolve_retry_seconds, NULL,
- ce->af, &ce->preresolved_local);
+ if (ce->bind_local && !ce->preresolved_local)
+ {
+ status = openvpn_getaddrinfo (flags, ce->local, ce->local_port,
+ c->options.resolve_retry_seconds, NULL,
+ ce->af, &ce->preresolved_local);
+
+ if (status != 0)
+ goto err;
+ gc_addspecial (ce->preresolved_local, &gc_freeaddrinfo_callback, &c->gc);
- if (status != 0)
- goto err;
}
}
return;
- err:
- throw_signal_soft (SIGUSR1, "Preresolving failed");
+ err:
+ throw_signal_soft (SIGHUP, "Preresolving failed");
}
/*
@@ -2640,30 +2643,6 @@ proto2ascii_all (struct gc_arena *gc)
return BSTR (&out);
}
-int
-addr_guess_family(sa_family_t af, const char *name)
-{
- unsigned short ret;
- if (af)
- {
- return af; /* already stamped */
- }
- else
- {
- struct addrinfo hints , *ai;
- int err;
- CLEAR(hints);
- hints.ai_flags = AI_NUMERICHOST;
- err = getaddrinfo(name, NULL, &hints, &ai);
- if ( 0 == err )
- {
- ret=ai->ai_family;
- freeaddrinfo(ai);
- return ret;
- }
- }
- return AF_INET; /* default */
-}
const char *
addr_family_name (int af)
{