summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2013-12-09 21:17:15 +0100
committerArne Schwabe <arne@rfc2549.org>2013-12-09 21:17:15 +0100
commit077f361f7a910ad0e95724a95e0d8b25af185bcc (patch)
treedc3eac4de8c10ad6627e49a694e87ff8884c2d5f
parent8fd784413142999a312d5300a1654a526b61b260 (diff)
Update pre resolve yet again
--HG-- extra : source : d87e130c3a907b46caedc89e651c65827a3508ed
-rw-r--r--build.gradle4
-rw-r--r--openvpn/src/openvpn/init.c16
-rw-r--r--openvpn/src/openvpn/openvpn.h3
-rw-r--r--openvpn/src/openvpn/options.h2
-rw-r--r--openvpn/src/openvpn/proxy.c2
-rw-r--r--openvpn/src/openvpn/proxy.h2
-rw-r--r--openvpn/src/openvpn/socket.c172
-rw-r--r--openvpn/src/openvpn/socket.h18
8 files changed, 177 insertions, 42 deletions
diff --git a/build.gradle b/build.gradle
index ea22c797..73532fbd 100644
--- a/build.gradle
+++ b/build.gradle
@@ -24,8 +24,8 @@ android {
defaultConfig {
minSdkVersion 14
targetSdkVersion 19
- versionCode = 82
- versionName = "0.6.1"
+ versionCode = 84
+ versionName = "0.6.3"
}
sourceSets {
diff --git a/openvpn/src/openvpn/init.c b/openvpn/src/openvpn/init.c
index 0f76b2cc..c42c0f78 100644
--- a/openvpn/src/openvpn/init.c
+++ b/openvpn/src/openvpn/init.c
@@ -130,16 +130,25 @@ management_callback_proxy_cmd (void *arg, const char **p)
#ifndef ENABLE_HTTP_PROXY
msg (M_WARN, "HTTP proxy support is not available");
#else
- struct http_proxy_options *ho;
- if (ce->proto != PROTO_TCP && ce->proto != PROTO_TCP_CLIENT ) {
+ struct http_proxy_options *ho, *oldho;
+ if (ce->proto != PROTO_TCP && ce->proto != PROTO_TCP_CLIENT ) {
msg (M_WARN, "HTTP proxy support only works for TCP based connections");
return false;
}
+ oldho = ce->http_proxy_options;
ho = init_http_proxy_options_once (&ce->http_proxy_options, gc);
ho->server = string_alloc (p[2], gc);
ho->port = string_alloc (p[3], gc);
ho->retry = true;
ho->auth_retry = (p[4] && streq (p[4], "nct") ? PAR_NCT : PAR_ALL);
+
+ /* Save the old preresolved addrinfo we are using the same proxy again */
+ if (oldho &&
+ oldho->preresolved_proxy &&
+ streq(oldho->server, ho->server) &&
+ streq(oldho->port, ho->port))
+ ho->preresolved_proxy = oldho->preresolved_proxy;
+
ret = true;
#endif
}
@@ -2690,10 +2699,9 @@ do_init_socket_1 (struct context *c, const int mode)
link_socket_init_phase1 (c->c2.link_socket,
c->options.ce.local,
c->options.ce.local_port,
- c->options.ce.preresolved_local,
c->options.ce.remote,
c->options.ce.remote_port,
- c->options.ce.preresolved_remote,
+ c->c1.preresolved,
c->options.ce.proto,
c->options.ce.af,
c->options.ce.bind_ipv6_only,
diff --git a/openvpn/src/openvpn/openvpn.h b/openvpn/src/openvpn/openvpn.h
index 606a4f59..3ed7810a 100644
--- a/openvpn/src/openvpn/openvpn.h
+++ b/openvpn/src/openvpn/openvpn.h
@@ -166,6 +166,9 @@ struct context_1
/* tunnel session keys */
struct key_schedule ks;
+ /* preresolved host names */
+ struct preresovled_host *preresolved;
+
/* persist crypto sequence number to/from file */
struct packet_id_persist pid_persist;
diff --git a/openvpn/src/openvpn/options.h b/openvpn/src/openvpn/options.h
index ddeb8b38..dafb8ff6 100644
--- a/openvpn/src/openvpn/options.h
+++ b/openvpn/src/openvpn/options.h
@@ -93,8 +93,6 @@ struct connection_entry
const char *remote_port;
const char *local;
const char *remote;
- struct addrinfo *preresolved_remote;
- struct addrinfo *preresolved_local;
bool remote_float;
bool bind_defined;
bool bind_ipv6_only;
diff --git a/openvpn/src/openvpn/proxy.c b/openvpn/src/openvpn/proxy.c
index f7f06487..53cd1cda 100644
--- a/openvpn/src/openvpn/proxy.c
+++ b/openvpn/src/openvpn/proxy.c
@@ -478,6 +478,8 @@ http_proxy_new (const struct http_proxy_options *o)
msg (M_FATAL, "Sorry, this version of " PACKAGE_NAME " was built without NTLM Proxy support.");
#endif
+ p->preresoveld_proxy = o->preresolved_proxy;
+
p->defined = true;
return p;
}
diff --git a/openvpn/src/openvpn/proxy.h b/openvpn/src/openvpn/proxy.h
index 0e7a6dfb..cea910cf 100644
--- a/openvpn/src/openvpn/proxy.h
+++ b/openvpn/src/openvpn/proxy.h
@@ -59,6 +59,7 @@ struct http_proxy_options {
const char *auth_file;
const char *http_version;
const char *user_agent;
+ struct addrinfo *preresolved_proxy;
struct http_custom_header custom_headers[MAX_CUSTOM_HTTP_HEADER];
};
@@ -73,6 +74,7 @@ struct http_proxy_info {
int auth_method;
struct http_proxy_options options;
struct user_pass up;
+ struct addrinfo* preresoveld_proxy;
char *proxy_authenticate;
bool queried_creds;
};
diff --git a/openvpn/src/openvpn/socket.c b/openvpn/src/openvpn/socket.c
index 26ef14c3..f99669aa 100644
--- a/openvpn/src/openvpn/socket.c
+++ b/openvpn/src/openvpn/socket.c
@@ -118,20 +118,114 @@ getaddr (unsigned int flags,
}
}
+static inline bool
+streqnull (const char* a, const char* b)
+{
+ if (a == NULL && b == NULL)
+ return true;
+ else if (a == NULL || b == NULL)
+ return false;
+ else
+ return streq (a, b);
+}
+
+static int
+get_preresolved_host (struct preresovled_host* preresolved,
+ const char* hostname,
+ const char* servname,
+ int ai_family,
+ int resolve_flags,
+ struct addrinfo **ai)
+{
+ struct preresovled_host *ph;
+ int flags;
+
+ /* Only use flags that are relevant for the structure */
+ flags = resolve_flags & GETADDR_PRERESOLVE_MASK;
+
+ for (ph = preresolved; ph ; ph = ph->next)
+ {
+ if (streqnull (ph->hostname, hostname) &&
+ streqnull (ph->servname, servname) &&
+ ph->ai_family == ai_family &&
+ ph->flags == flags)
+ {
+ *ai = ph->ai;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+
+static int
+do_preresolve_host (struct context *c,
+ const char *hostname,
+ const char *servname,
+ const int af,
+ const int flags)
+{
+ struct addrinfo *ai;
+ if (get_preresolved_host(c->c1.preresolved,
+ hostname,
+ servname,
+ af,
+ flags,
+ &ai))
+ {
+ int status;
+ status = openvpn_getaddrinfo (flags, hostname, servname,
+ c->options.resolve_retry_seconds, NULL,
+ af, &ai);
+ if (status == 0)
+ {
+ struct preresovled_host *ph;
+
+ ALLOC_OBJ_CLEAR_GC (ph, struct preresovled_host, &c->gc);
+ ph->ai = ai;
+ ph->hostname = hostname;
+ ph->servname = servname;
+ ph->flags = flags & GETADDR_PRERESOLVE_MASK;
+
+ if (!c->c1.preresolved)
+ c->c1.preresolved = ph;
+ else
+ {
+ struct preresovled_host *prev = c->c1.preresolved;
+ while (prev->next)
+ prev = prev->next;
+ prev->next = ph;
+ }
+
+ gc_addspecial (ai, &gc_freeaddrinfo_callback, &c->gc);
+
+ }
+ return status;
+ }
+ else
+ {
+ /* already in preresolved list, return success */
+ return 0;
+ }
+}
void
do_preresolve(struct context *c)
{
int i;
struct connection_list *l = c->options.connection_list;
+ const unsigned int preresolve_flags = GETADDR_RESOLVE|
+ GETADDR_UPDATE_MANAGEMENT_STATE|
+ GETADDR_MENTION_RESOLVE_RETRY|
+ GETADDR_FATAL;
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];
- unsigned int flags = GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE|
- GETADDR_MENTION_RESOLVE_RETRY|GETADDR_FATAL;
if (proto_is_dgram(ce->proto))
flags |= GETADDR_DATAGRAM;
@@ -144,28 +238,45 @@ do_preresolve(struct context *c)
else
remote = ce->remote;
- if (! ce->preresolved_remote)
+ /* HTTP remote hostname does not need to be resolved */
+ if (! ce->http_proxy_options)
{
- status = openvpn_getaddrinfo (flags, remote, ce->remote_port,
- c->options.resolve_retry_seconds, NULL,
- ce->af, &ce->preresolved_remote);
-
- if (status != 0)
+ status = do_preresolve_host (c, remote, ce->remote_port, ce->af, flags);
+ if (!status)
goto err;
- gc_addspecial (ce->preresolved_remote, &gc_freeaddrinfo_callback, &c->gc);
}
flags |= GETADDR_PASSIVE;
- if (ce->bind_local && !ce->preresolved_local)
+
+ if (ce->bind_local)
{
- status = openvpn_getaddrinfo (flags, ce->local, ce->local_port,
- c->options.resolve_retry_seconds, NULL,
- ce->af, &ce->preresolved_local);
+ status = do_preresolve_host (c, ce->local, ce->local_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;
- gc_addspecial (ce->preresolved_local, &gc_freeaddrinfo_callback, &c->gc);
+ }
+ 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;
}
}
@@ -1211,12 +1322,14 @@ resolve_bind_local (struct link_socket *sock, const sa_family_t af)
flags |= GETADDR_DATAGRAM;
/* will return AF_{INET|INET6}from local_host */
- if (sock->preresolved_local)
- {
- status=0;
- sock->info.lsa->bind_local=sock->preresolved_local;
- }
- else
+ status = get_preresolved_host (sock->preresolved,
+ sock->local_host,
+ sock->local_port,
+ af,
+ flags,
+ &sock->info.lsa->bind_local);
+
+ if (status)
status = openvpn_getaddrinfo(flags, sock->local_host, sock->local_port, 0,
NULL, af, &sock->info.lsa->bind_local);
@@ -1302,12 +1415,13 @@ resolve_remote (struct link_socket *sock,
ASSERT (0);
}
- if (sock->preresolved_remote)
- {
- status = 0;
- ai = sock->preresolved_remote;
- }
- else
+
+ status = get_preresolved_host (sock->preresolved,
+ sock->remote_host,
+ sock->remote_port,
+ sock->info.af,
+ flags, &ai);
+ if (status)
status = openvpn_getaddrinfo (flags, sock->remote_host, sock->remote_port,
retry, signal_received, sock->info.af, &ai);
@@ -1412,10 +1526,9 @@ void
link_socket_init_phase1 (struct link_socket *sock,
const char *local_host,
const char *local_port,
- struct addrinfo *local_preresolved,
const char *remote_host,
const char *remote_port,
- struct addrinfo *remote_preresolved,
+ struct preresovled_host *preresolved,
int proto,
sa_family_t af,
bool bind_ipv6_only,
@@ -1448,10 +1561,9 @@ link_socket_init_phase1 (struct link_socket *sock,
sock->local_host = local_host;
sock->local_port = local_port;
- sock->preresolved_local = local_preresolved;
sock->remote_host = remote_host;
sock->remote_port = remote_port;
- sock->preresolved_remote = remote_preresolved;
+ sock->preresolved = preresolved;
#ifdef ENABLE_HTTP_PROXY
sock->http_proxy = http_proxy;
diff --git a/openvpn/src/openvpn/socket.h b/openvpn/src/openvpn/socket.h
index 8a118cd1..7c0b040c 100644
--- a/openvpn/src/openvpn/socket.h
+++ b/openvpn/src/openvpn/socket.h
@@ -77,6 +77,16 @@ struct openvpn_sockaddr
} addr;
};
+/* struct to hold preresolved host names */
+struct preresovled_host {
+ const char *hostname;
+ const char *servname;
+ int ai_family;
+ int flags;
+ struct addrinfo *ai;
+ struct preresovled_host *next;
+};
+
/* actual address of remote, based on source address of received packets */
struct link_socket_actual
{
@@ -186,10 +196,9 @@ struct link_socket
const char *remote_host;
const char *remote_port;
- struct addrinfo *preresolved_remote;
const char *local_host;
const char *local_port;
- struct addrinfo *preresolved_local;
+ struct preresovled_host *preresolved;
bool bind_local;
# define INETD_NONE 0
@@ -308,10 +317,9 @@ void
link_socket_init_phase1 (struct link_socket *sock,
const char *local_host,
const char *local_port,
- struct addrinfo *local_preresolved,
const char *remote_host,
const char *remote_port,
- struct addrinfo *remote_preresolved,
+ struct preresovled_host *preresolved,
int proto,
sa_family_t af,
bool bind_ipv6_only,
@@ -520,6 +528,8 @@ bool unix_socket_get_peer_uid_gid (const socket_descriptor_t sd, int *uid, int *
#define GETADDR_PASSIVE (1<<10)
#define GETADDR_DATAGRAM (1<<11)
+#define GETADDR_PRERESOLVE_MASK GETADDR_DATAGRAM|GETADDR_PASSIVE
+
in_addr_t getaddr (unsigned int flags,
const char *hostname,
int resolve_retry_seconds,