summaryrefslogtreecommitdiff
path: root/openvpn/src/openvpn/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'openvpn/src/openvpn/socket.c')
-rw-r--r--openvpn/src/openvpn/socket.c196
1 files changed, 100 insertions, 96 deletions
diff --git a/openvpn/src/openvpn/socket.c b/openvpn/src/openvpn/socket.c
index e88148a0..716512df 100644
--- a/openvpn/src/openvpn/socket.c
+++ b/openvpn/src/openvpn/socket.c
@@ -130,20 +130,20 @@ streqnull (const char* a, const char* b)
}
static int
-get_preresolved_host (struct preresovled_host* preresolved,
+get_cached_dns_entry (struct cached_dns_entry* dns_cache,
const char* hostname,
const char* servname,
int ai_family,
int resolve_flags,
struct addrinfo **ai)
{
- struct preresovled_host *ph;
+ struct cached_dns_entry *ph;
int flags;
/* Only use flags that are relevant for the structure */
- flags = resolve_flags & GETADDR_PRERESOLVE_MASK;
+ flags = resolve_flags & GETADDR_CACHE_MASK;
- for (ph = preresolved; ph ; ph = ph->next)
+ for (ph = dns_cache; ph ; ph = ph->next)
{
if (streqnull (ph->hostname, hostname) &&
streqnull (ph->servname, servname) &&
@@ -166,7 +166,7 @@ do_preresolve_host (struct context *c,
const int flags)
{
struct addrinfo *ai;
- if (get_preresolved_host(c->c1.preresolved,
+ if (get_cached_dns_entry(c->c1.dns_cache,
hostname,
servname,
af,
@@ -179,19 +179,19 @@ do_preresolve_host (struct context *c,
af, &ai);
if (status == 0)
{
- struct preresovled_host *ph;
+ struct cached_dns_entry *ph;
- ALLOC_OBJ_CLEAR_GC (ph, struct preresovled_host, &c->gc);
+ ALLOC_OBJ_CLEAR_GC (ph, struct cached_dns_entry, &c->gc);
ph->ai = ai;
ph->hostname = hostname;
ph->servname = servname;
- ph->flags = flags & GETADDR_PRERESOLVE_MASK;
+ ph->flags = flags & GETADDR_CACHE_MASK;
- if (!c->c1.preresolved)
- c->c1.preresolved = ph;
+ if (!c->c1.dns_cache)
+ c->c1.dns_cache = ph;
else
{
- struct preresovled_host *prev = c->c1.preresolved;
+ struct cached_dns_entry *prev = c->c1.dns_cache;
while (prev->next)
prev = prev->next;
prev->next = ph;
@@ -204,13 +204,13 @@ do_preresolve_host (struct context *c,
}
else
{
- /* already in preresolved list, return success */
+ /* already in cached dns list, return success */
return 0;
}
}
void
-do_preresolve(struct context *c)
+do_preresolve (struct context *c)
{
int i;
struct connection_list *l = c->options.connection_list;
@@ -220,67 +220,69 @@ do_preresolve(struct context *c)
GETADDR_FATAL;
- for (i = 0; i < l->len; ++i) {
- int status;
- const char *remote;
- int flags = preresolve_flags;
+ for (i = 0; i < l->len; ++i)
+ {
+ int status;
+ const char *remote;
+ int flags = preresolve_flags;
- struct connection_entry* ce = c->options.connection_list->array[i];
+ struct connection_entry* ce = c->options.connection_list->array[i];
- if (proto_is_dgram(ce->proto))
- flags |= GETADDR_DATAGRAM;
+ if (proto_is_dgram(ce->proto))
+ flags |= GETADDR_DATAGRAM;
- if (c->options.sockflags & SF_HOST_RANDOMIZE)
- flags |= GETADDR_RANDOMIZE;
+ if (c->options.sockflags & SF_HOST_RANDOMIZE)
+ flags |= GETADDR_RANDOMIZE;
- if (c->options.ip_remote_hint)
- remote = c->options.ip_remote_hint;
- else
- remote = ce->remote;
+ if (c->options.ip_remote_hint)
+ remote = c->options.ip_remote_hint;
+ else
+ remote = ce->remote;
- /* HTTP remote hostname does not need to be resolved */
- if (! ce->http_proxy_options)
- {
- status = do_preresolve_host (c, remote, ce->remote_port, ce->af, flags);
- if (status != 0)
- goto err;
- }
+ /* HTTP remote hostname does not need to be resolved */
+ if (! ce->http_proxy_options)
+ {
+ status = do_preresolve_host (c, remote, ce->remote_port, ce->af, flags);
+ if (status != 0)
+ goto err;
+ }
- flags |= GETADDR_PASSIVE;
+ /* Preresolve proxy */
+ if (ce->http_proxy_options)
+ {
+ status = do_preresolve_host (c,
+ ce->http_proxy_options->server,
+ ce->http_proxy_options->port,
+ ce->af,
+ preresolve_flags);
+
+ if (status != 0)
+ goto err;
+ }
- if (ce->bind_local)
- {
- status = do_preresolve_host (c, ce->local, ce->local_port, ce->af, flags);
- if (status != 0)
- goto err;
+ if (ce->socks_proxy_server)
+ {
+ status = do_preresolve_host (c,
+ ce->socks_proxy_server,
+ ce->socks_proxy_port,
+ ce->af,
+ flags);
+ if (status != 0)
+ goto err;
+ }
- }
- /* Preresolve proxy */
- if (ce->http_proxy_options)
- {
- status = do_preresolve_host(c,
- ce->http_proxy_options->server,
- ce->http_proxy_options->port,
- ce->af,
- preresolve_flags);
-
- if (status != 0)
- goto err;
- }
+ if (ce->bind_local)
+ {
+ flags |= GETADDR_PASSIVE;
+ flags &= ~GETADDR_RANDOMIZE;
+ status = do_preresolve_host (c, ce->local, ce->local_port, ce->af, flags);
+ if (status != 0)
+ goto err;
- if (ce->socks_proxy_server)
- {
- status = do_preresolve_host (c,
- ce->socks_proxy_server,
- ce->socks_proxy_port,
- ce->af,
- flags);
- if (status != 0)
- goto err;
- }
+ }
- }
- return;
+ }
+ return;
err:
throw_signal_soft (SIGHUP, "Preresolving failed");
@@ -1083,8 +1085,9 @@ socket_bind (socket_descriptor_t sd,
if (ai_family == AF_INET6)
{
- int v6only = ipv6only ? 0: 1; /* setsockopt must have an "int" */
+ int v6only = ipv6only ? 1: 0; /* setsockopt must have an "int" */
+ msg (M_INFO, "setsockopt(IPV6_V6ONLY=%d)", v6only);
if (setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)))
{
msg (M_NONFATAL|M_ERRNO, "Setting IPV6_V6ONLY=%d failed", v6only);
@@ -1322,7 +1325,7 @@ resolve_bind_local (struct link_socket *sock, const sa_family_t af)
flags |= GETADDR_DATAGRAM;
/* will return AF_{INET|INET6}from local_host */
- status = get_preresolved_host (sock->preresolved,
+ status = get_cached_dns_entry (sock->dns_cache,
sock->local_host,
sock->local_port,
af,
@@ -1416,7 +1419,7 @@ resolve_remote (struct link_socket *sock,
}
- status = get_preresolved_host (sock->preresolved,
+ status = get_cached_dns_entry (sock->dns_cache,
sock->remote_host,
sock->remote_port,
sock->info.af,
@@ -1441,12 +1444,12 @@ resolve_remote (struct link_socket *sock,
if (*signal_received)
goto done;
}
- if (status!=0)
- {
- if (signal_received)
- *signal_received = SIGUSR1;
- goto done;
- }
+ if (status!=0)
+ {
+ if (signal_received)
+ *signal_received = SIGUSR1;
+ goto done;
+ }
}
}
@@ -1458,15 +1461,15 @@ resolve_remote (struct link_socket *sock,
if (remote_dynamic)
*remote_dynamic = NULL;
}
- /* else, quick hack to fix persistent-remote ....*/
- {
- CLEAR (sock->info.lsa->actual);
- if(sock->info.lsa->current_remote)
- {
- set_actual_address (&sock->info.lsa->actual,
- sock->info.lsa->current_remote);
- }
- }
+ else
+ {
+ CLEAR (sock->info.lsa->actual);
+ if(sock->info.lsa->current_remote)
+ {
+ set_actual_address (&sock->info.lsa->actual,
+ sock->info.lsa->current_remote);
+ }
+ }
done:
gc_free (&gc);
@@ -1506,21 +1509,10 @@ create_new_socket (struct link_socket* sock)
/* clear destination set by set_actual_address */
CLEAR(sock->info.lsa->actual.dest);
}
-
- /*
- * Create the socket early if socket should be bound
- */
- if (sock->bind_local)
- {
- create_socket (sock);
-
- if (sock->bind_local)
- bind_local(sock);
- }
-
}
+
/* bind socket if necessary */
void
link_socket_init_phase1 (struct link_socket *sock,
@@ -1528,7 +1520,7 @@ link_socket_init_phase1 (struct link_socket *sock,
const char *local_port,
const char *remote_host,
const char *remote_port,
- struct preresovled_host *preresolved,
+ struct cached_dns_entry *dns_cache,
int proto,
sa_family_t af,
bool bind_ipv6_only,
@@ -1563,7 +1555,7 @@ link_socket_init_phase1 (struct link_socket *sock,
sock->local_port = local_port;
sock->remote_host = remote_host;
sock->remote_port = remote_port;
- sock->preresolved = preresolved;
+ sock->dns_cache = dns_cache;
#ifdef ENABLE_HTTP_PROXY
sock->http_proxy = http_proxy;
@@ -1742,6 +1734,7 @@ linksock_print_addr (struct link_socket *sock)
struct gc_arena gc = gc_new ();
const int msglevel = (sock->mode == LS_MODE_TCP_ACCEPT_FROM) ? D_INIT_MEDIUM : M_INFO;
+ /* print local address */
if (sock->inetd)
msg (msglevel, "%s link local: [inetd]", proto2ascii (sock->info.proto, sock->info.af, true));
else if (sock->bind_local)
@@ -1942,6 +1935,17 @@ link_socket_init_phase2 (struct link_socket *sock,
/* If socket has not already been created create it now */
if (sock->sd == SOCKET_UNDEFINED)
{
+ /* If we have no --remote and have still not figured out the
+ * protocol family to use we will use the first of the bind */
+ if (sock->bind_local && sock->info.lsa->bind_local
+ && !sock->info.lsa->actual.ai_family && !sock->remote_host)
+ {
+ msg (M_WARN, "Could not determine IPv4/IPv6 protocol. Using %s",
+ addr_family_name(sock->info.lsa->bind_local->ai_family));
+ set_actual_address(&sock->info.lsa->actual, sock->info.lsa->bind_local);
+
+ }
+
if (sock->info.lsa->actual.ai_family)
{
create_socket (sock);