summaryrefslogtreecommitdiff
path: root/app/openvpn/src/openvpn/socket.h
diff options
context:
space:
mode:
Diffstat (limited to 'app/openvpn/src/openvpn/socket.h')
-rw-r--r--app/openvpn/src/openvpn/socket.h169
1 files changed, 95 insertions, 74 deletions
diff --git a/app/openvpn/src/openvpn/socket.h b/app/openvpn/src/openvpn/socket.h
index 5b7a26a9..8e157c67 100644
--- a/app/openvpn/src/openvpn/socket.h
+++ b/app/openvpn/src/openvpn/socket.h
@@ -77,15 +77,21 @@ struct openvpn_sockaddr
} addr;
};
+/* struct to hold preresolved host names */
+struct cached_dns_entry {
+ const char *hostname;
+ const char *servname;
+ int ai_family;
+ int flags;
+ struct addrinfo *ai;
+ struct cached_dns_entry *next;
+};
+
/* actual address of remote, based on source address of received packets */
struct link_socket_actual
{
/*int dummy;*/ /* add offset to force a bug if dest not explicitly dereferenced */
- int ai_family; /* PF_xxx */
- int ai_socktype; /* SOCK_xxx */
- int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
-
struct openvpn_sockaddr dest;
#if ENABLE_IP_PKTINFO
union {
@@ -104,7 +110,7 @@ struct link_socket_addr
{
struct addrinfo* bind_local;
struct addrinfo* remote_list; /* complete remote list */
- struct addrinfo* current_remote; /* remote used in the
+ struct addrinfo* current_remote; /* remote used in the
current connection attempt */
struct link_socket_actual actual; /* reply to this address */
};
@@ -118,6 +124,7 @@ struct link_socket_info
bool remote_float;
int proto; /* Protocol (PROTO_x defined below) */
sa_family_t af; /* Address family like AF_INET, AF_INET6 or AF_UNSPEC*/
+ bool bind_ipv6_only;
int mtu_changed; /* Set to true when mtu value is changed */
};
@@ -165,10 +172,7 @@ struct link_socket
struct link_socket_info info;
socket_descriptor_t sd;
-
-#ifdef ENABLE_SOCKS
socket_descriptor_t ctrl_sd; /* only used for UDP over Socks */
-#endif
#ifdef WIN32
struct overlapped_io reads;
@@ -187,6 +191,7 @@ struct link_socket
const char *remote_port;
const char *local_host;
const char *local_port;
+ struct cached_dns_entry *dns_cache;
bool bind_local;
# define INETD_NONE 0
@@ -207,8 +212,6 @@ struct link_socket
int mtu; /* OS discovered MTU, or 0 if unknown */
- bool did_resolve_remote;
-
# define SF_USE_IP_PKTINFO (1<<0)
# define SF_TCP_NODELAY (1<<1)
# define SF_PORT_SHARE (1<<2)
@@ -222,22 +225,16 @@ struct link_socket
struct buffer stream_buf_data;
bool stream_reset;
-#ifdef ENABLE_HTTP_PROXY
/* HTTP proxy */
struct http_proxy_info *http_proxy;
-#endif
-#ifdef ENABLE_SOCKS
/* Socks proxy */
struct socks_proxy_info *socks_proxy;
struct link_socket_actual socks_relay; /* Socks UDP relay address */
-#endif
-#if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_SOCKS)
/* The OpenVPN server we will use the proxy to connect to */
const char *proxy_dest_host;
const char *proxy_dest_port;
-#endif
#if PASSTOS_CAPABILITY
/* used to get/set TOS. */
@@ -289,13 +286,16 @@ struct link_socket *link_socket_new (void);
void socket_bind (socket_descriptor_t sd,
struct addrinfo *local,
int af_family,
- const char *prefix);
+ const char *prefix,
+ bool ipv6only);
int openvpn_connect (socket_descriptor_t sd,
const struct sockaddr *remote,
int connect_timeout,
volatile int *signal_received);
+
+
/*
* Initialize link_socket object.
*/
@@ -306,16 +306,14 @@ link_socket_init_phase1 (struct link_socket *sock,
const char *local_port,
const char *remote_host,
const char *remote_port,
+ struct cached_dns_entry *dns_cache,
int proto,
- sa_family_t af,
+ sa_family_t af,
+ bool bind_ipv6_only,
int mode,
const struct link_socket *accept_from,
-#ifdef ENABLE_HTTP_PROXY
struct http_proxy_info *http_proxy,
-#endif
-#ifdef ENABLE_SOCKS
struct socks_proxy_info *socks_proxy,
-#endif
#ifdef ENABLE_DEBUG
int gremlin,
#endif
@@ -337,6 +335,8 @@ void link_socket_init_phase2 (struct link_socket *sock,
const struct frame *frame,
struct signal_info *sig_info);
+void do_preresolve(struct context *c);
+
void socket_adjust_frame_parameters (struct frame *frame, int proto);
void frame_adjust_path_mtu (struct frame *frame, int pmtu, int proto);
@@ -456,7 +456,7 @@ bool ip_or_dns_addr_safe (const char *addr, const bool allow_fqdn);
bool mac_addr_safe (const char *mac_addr);
bool ipv6_addr_safe (const char *ipv6_text_addr);
-socket_descriptor_t create_socket_tcp (int af);
+socket_descriptor_t create_socket_tcp (struct addrinfo*);
socket_descriptor_t socket_do_accept (socket_descriptor_t sd,
struct link_socket_actual *act,
@@ -511,6 +511,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_CACHE_MASK (GETADDR_DATAGRAM|GETADDR_PASSIVE)
+
in_addr_t getaddr (unsigned int flags,
const char *hostname,
int resolve_retry_seconds,
@@ -600,14 +602,14 @@ static inline bool
addr_local (const struct sockaddr *addr)
{
if (!addr)
- return false;
+ return false;
switch (addr->sa_family) {
- case AF_INET:
- return ((const struct sockaddr_in*)addr)->sin_addr.s_addr == htonl(INADDR_LOOPBACK);
- case AF_INET6:
- return IN6_IS_ADDR_LOOPBACK(&((const struct sockaddr_in6*)addr)->sin6_addr);
- default:
- return false;
+ case AF_INET:
+ return ((const struct sockaddr_in*)addr)->sin_addr.s_addr == htonl(INADDR_LOOPBACK);
+ case AF_INET6:
+ return IN6_IS_ADDR_LOOPBACK(&((const struct sockaddr_in6*)addr)->sin6_addr);
+ default:
+ return false;
}
}
@@ -641,61 +643,78 @@ link_socket_actual_defined (const struct link_socket_actual *act)
static inline bool
addr_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockaddr *a2)
{
- switch(a1->addr.sa.sa_family) {
- case AF_INET:
- return a1->addr.in4.sin_addr.s_addr == a2->addr.in4.sin_addr.s_addr;
- case AF_INET6:
- return IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &a2->addr.in6.sin6_addr);
- }
- ASSERT(0);
- return false;
+ switch(a1->addr.sa.sa_family) {
+ case AF_INET:
+ return a1->addr.in4.sin_addr.s_addr == a2->addr.in4.sin_addr.s_addr;
+ case AF_INET6:
+ return IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &a2->addr.in6.sin6_addr);
+ }
+ ASSERT(0);
+ return false;
}
static inline bool
addrlist_match (const struct openvpn_sockaddr *a1, const struct addrinfo *addrlist)
{
const struct addrinfo *curele;
- for (curele = addrlist; curele; curele=curele->ai_next) {
-
- switch(a1->addr.sa.sa_family) {
- case AF_INET:
- if (a1->addr.in4.sin_addr.s_addr == ((struct sockaddr_in*)curele->ai_addr)->sin_addr.s_addr)
- return true;
- break;
- case AF_INET6:
- if (IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &((struct sockaddr_in6*) curele->ai_addr)->sin6_addr))
- return true;
- break;
- default:
- ASSERT(0);
+ for (curele = addrlist; curele; curele=curele->ai_next)
+ {
+ switch(a1->addr.sa.sa_family)
+ {
+ case AF_INET:
+ if (a1->addr.in4.sin_addr.s_addr == ((struct sockaddr_in*)curele->ai_addr)->sin_addr.s_addr)
+ return true;
+ break;
+ case AF_INET6:
+ if (IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &((struct sockaddr_in6*) curele->ai_addr)->sin6_addr))
+ return true;
+ break;
+ default:
+ ASSERT(0);
+ }
}
- }
return false;
}
+static inline in_addr_t
+addr_host (const struct openvpn_sockaddr *addr)
+{
+ /*
+ * "public" addr returned is checked against ifconfig for
+ * possible clash: non sense for now given
+ * that we do ifconfig only IPv4
+ */
+ if(addr->addr.sa.sa_family != AF_INET)
+ return 0;
+ return ntohl (addr->addr.in4.sin_addr.s_addr);
+}
+
+
static inline bool
addrlist_port_match (const struct openvpn_sockaddr *a1, const struct addrinfo *a2)
{
- const struct addrinfo *curele;
- for(curele=a2;curele;curele = curele->ai_next) {
- switch(a1->addr.sa.sa_family) {
- case AF_INET:
+ const struct addrinfo *curele;
+ for(curele=a2;curele;curele = curele->ai_next)
+ {
+ switch(a1->addr.sa.sa_family)
+ {
+ case AF_INET:
if (curele->ai_family == AF_INET
&& a1->addr.in4.sin_addr.s_addr == ((struct sockaddr_in*)curele->ai_addr)->sin_addr.s_addr
&& a1->addr.in4.sin_port == ((struct sockaddr_in*)curele->ai_addr)->sin_port)
return true;
break;
- case AF_INET6:
+ case AF_INET6:
if (curele->ai_family == AF_INET6
&& IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &((struct sockaddr_in6*) curele->ai_addr)->sin6_addr)
&& a1->addr.in6.sin6_port == ((struct sockaddr_in6*) curele->ai_addr)->sin6_port)
return true;
break;
- default:
+ default:
ASSERT(0);
}
}
- return false;
+ return false;
}
@@ -708,7 +727,7 @@ addr_port_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockadd
return a1->addr.in4.sin_addr.s_addr == a2->addr.in4.sin_addr.s_addr
&& a1->addr.in4.sin_port == a2->addr.in4.sin_port;
case AF_INET6:
- return IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &a2->addr.in6.sin6_addr)
+ return IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &a2->addr.in6.sin6_addr)
&& a1->addr.in6.sin6_port == a2->addr.in6.sin6_port;
}
ASSERT(0);
@@ -717,10 +736,10 @@ addr_port_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockadd
static inline bool
addr_match_proto (const struct openvpn_sockaddr *a1,
- const struct openvpn_sockaddr *a2,
- const int proto)
+ const struct openvpn_sockaddr *a2,
+ const int proto)
{
- return link_socket_proto_connection_oriented (proto)
+ return link_socket_proto_connection_oriented (proto)
? addr_match (a1, a2)
: addr_port_match (a1, a2);
}
@@ -728,8 +747,8 @@ addr_match_proto (const struct openvpn_sockaddr *a1,
static inline bool
addrlist_match_proto (const struct openvpn_sockaddr *a1,
- struct addrinfo *addr_list,
- const int proto)
+ struct addrinfo *addr_list,
+ const int proto)
{
return link_socket_proto_connection_oriented (proto)
? addrlist_match (a1, addr_list)
@@ -839,7 +858,7 @@ link_socket_verify_incoming_addr (struct buffer *buf,
case AF_INET:
if (!link_socket_actual_defined (from_addr))
return false;
- if (info->remote_float || !info->lsa->remote_list)
+ if (info->remote_float || (!info->lsa->remote_list))
return true;
if (addrlist_match_proto (&from_addr->dest, info->lsa->remote_list, info->proto))
return true;
@@ -878,13 +897,15 @@ link_socket_set_outgoing_addr (const struct buffer *buf,
{
struct link_socket_addr *lsa = info->lsa;
if (
- /* new or changed address? */
- (!info->connection_established
- || !addr_match_proto (&act->dest, &lsa->actual.dest, info->proto))
- /* address undef or address == remote or --float */
- && (info->remote_float
- || !lsa->remote_list)
- || addrlist_match_proto (&act->dest, lsa->remote_list, info->proto)
+ /* new or changed address? */
+ (!info->connection_established
+ || !addr_match_proto (&act->dest, &lsa->actual.dest, info->proto)
+ )
+ &&
+ /* address undef or address == remote or --float */
+ (info->remote_float ||
+ (!lsa->remote_list || addrlist_match_proto (&act->dest, lsa->remote_list, info->proto))
+ )
)
{
link_socket_connection_initiated (buf, info, act, common_name, es);
@@ -1095,7 +1116,7 @@ static inline void
link_socket_set_tos (struct link_socket *ls)
{
if (ls && ls->ptos_defined)
- setsockopt (ls->sd, IPPROTO_IP, IP_TOS, &ls->ptos, sizeof (ls->ptos));
+ setsockopt (ls->sd, IPPROTO_IP, IP_TOS, (const void *)&ls->ptos, sizeof (ls->ptos));
}
#endif