Pass sockets to bypass to kernel interface, allowing us to register them dynamically
This commit is contained in:
@@ -241,6 +241,15 @@ METHOD(kernel_interface_t, del_route, status_t,
|
|||||||
src_ip, if_name);
|
src_ip, if_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(kernel_interface_t, bypass_socket, bool,
|
||||||
|
private_kernel_interface_t *this, int fd, int family)
|
||||||
|
{
|
||||||
|
if (!this->ipsec)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return this->ipsec->bypass_socket(this->ipsec, fd, family);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(kernel_interface_t, get_address_by_ts, status_t,
|
METHOD(kernel_interface_t, get_address_by_ts, status_t,
|
||||||
private_kernel_interface_t *this, traffic_selector_t *ts, host_t **ip)
|
private_kernel_interface_t *this, traffic_selector_t *ts, host_t **ip)
|
||||||
@@ -361,6 +370,7 @@ kernel_interface_t *kernel_interface_create()
|
|||||||
.del_ip = _del_ip,
|
.del_ip = _del_ip,
|
||||||
.add_route = _add_route,
|
.add_route = _add_route,
|
||||||
.del_route = _del_route,
|
.del_route = _del_route,
|
||||||
|
.bypass_socket = _bypass_socket,
|
||||||
|
|
||||||
.get_address_by_ts = _get_address_by_ts,
|
.get_address_by_ts = _get_address_by_ts,
|
||||||
.add_ipsec_interface = _add_ipsec_interface,
|
.add_ipsec_interface = _add_ipsec_interface,
|
||||||
|
|||||||
@@ -332,6 +332,15 @@ struct kernel_interface_t {
|
|||||||
status_t (*del_route) (kernel_interface_t *this, chunk_t dst_net, u_int8_t prefixlen,
|
status_t (*del_route) (kernel_interface_t *this, chunk_t dst_net, u_int8_t prefixlen,
|
||||||
host_t *gateway, host_t *src_ip, char *if_name);
|
host_t *gateway, host_t *src_ip, char *if_name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up a bypass policy for a given socket.
|
||||||
|
*
|
||||||
|
* @param fd socket file descriptor to setup policy for
|
||||||
|
* @param family protocol family of the socket
|
||||||
|
* @return TRUE of policy set up successfully
|
||||||
|
*/
|
||||||
|
bool (*bypass_socket)(kernel_interface_t *this, int fd, int family);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* manager methods
|
* manager methods
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -264,6 +264,15 @@ struct kernel_ipsec_t {
|
|||||||
policy_dir_t direction,
|
policy_dir_t direction,
|
||||||
bool unrouted);
|
bool unrouted);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install a bypass policy for the given socket.
|
||||||
|
*
|
||||||
|
* @param fd socket file descriptor to setup policy for
|
||||||
|
* @param family protocol family of the socket
|
||||||
|
* @return TRUE of policy set up successfully
|
||||||
|
*/
|
||||||
|
bool (*bypass_socket)(kernel_ipsec_t *this, int fd, int family);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy the implementation.
|
* Destroy the implementation.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -59,13 +59,6 @@ struct socket_t {
|
|||||||
* - FAILED when unable to send
|
* - FAILED when unable to send
|
||||||
*/
|
*/
|
||||||
status_t (*send) (socket_t *this, packet_t *packet);
|
status_t (*send) (socket_t *this, packet_t *packet);
|
||||||
|
|
||||||
/**
|
|
||||||
* Enumerate all underlying socket file descriptors.
|
|
||||||
*
|
|
||||||
* @return enumerator over (int fd, int family, int port)
|
|
||||||
*/
|
|
||||||
enumerator_t *(*create_enumerator) (socket_t *this);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /** SOCKET_H_ @}*/
|
#endif /** SOCKET_H_ @}*/
|
||||||
|
|||||||
@@ -81,21 +81,6 @@ METHOD(socket_manager_t, sender, status_t,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(socket_manager_t, create_enumerator, enumerator_t*,
|
|
||||||
private_socket_manager_t *this)
|
|
||||||
{
|
|
||||||
socket_t *socket;
|
|
||||||
|
|
||||||
this->lock->read_lock(this->lock);
|
|
||||||
if (this->sockets->get_first(this->sockets, (void**)&socket) != SUCCESS)
|
|
||||||
{
|
|
||||||
this->lock->unlock(this->lock);
|
|
||||||
return enumerator_create_empty();
|
|
||||||
}
|
|
||||||
return enumerator_create_cleaner(socket->create_enumerator(socket),
|
|
||||||
(void*)this->lock->unlock, this->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(socket_manager_t, add_socket, void,
|
METHOD(socket_manager_t, add_socket, void,
|
||||||
private_socket_manager_t *this, socket_t *socket)
|
private_socket_manager_t *this, socket_t *socket)
|
||||||
{
|
{
|
||||||
@@ -131,7 +116,6 @@ socket_manager_t *socket_manager_create()
|
|||||||
.public = {
|
.public = {
|
||||||
.send = _sender,
|
.send = _sender,
|
||||||
.receive = _receiver,
|
.receive = _receiver,
|
||||||
.create_enumerator = _create_enumerator,
|
|
||||||
.add_socket = _add_socket,
|
.add_socket = _add_socket,
|
||||||
.remove_socket = _remove_socket,
|
.remove_socket = _remove_socket,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
|
|||||||
@@ -50,13 +50,6 @@ struct socket_manager_t {
|
|||||||
*/
|
*/
|
||||||
status_t (*send) (socket_manager_t *this, packet_t *packet);
|
status_t (*send) (socket_manager_t *this, packet_t *packet);
|
||||||
|
|
||||||
/**
|
|
||||||
* Enumerate all underlying socket file descriptors of the active socket.
|
|
||||||
*
|
|
||||||
* @return enumerator over (int fd, int family, int port)
|
|
||||||
*/
|
|
||||||
enumerator_t *(*create_enumerator) (socket_manager_t *this);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a socket implementation.
|
* Register a socket implementation.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2556,6 +2556,13 @@ static status_t register_pfkey_socket(private_kernel_klips_ipsec_t *this, u_int8
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(kernel_ipsec_t, bypass_socket, bool,
|
||||||
|
private_kernel_klips_ipsec_t *this, int fd, int family)
|
||||||
|
{
|
||||||
|
/* KLIPS does not need a bypass policy for IKE */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(kernel_ipsec_t, destroy, void,
|
METHOD(kernel_ipsec_t, destroy, void,
|
||||||
private_kernel_klips_ipsec_t *this)
|
private_kernel_klips_ipsec_t *this)
|
||||||
{
|
{
|
||||||
@@ -2589,6 +2596,7 @@ kernel_klips_ipsec_t *kernel_klips_ipsec_create()
|
|||||||
.add_policy = _add_policy,
|
.add_policy = _add_policy,
|
||||||
.query_policy = _query_policy,
|
.query_policy = _query_policy,
|
||||||
.del_policy = _del_policy,
|
.del_policy = _del_policy,
|
||||||
|
.bypass_socket = _bypass_socket,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.policies = linked_list_create(),
|
.policies = linked_list_create(),
|
||||||
|
|||||||
@@ -1892,6 +1892,47 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(kernel_ipsec_t, bypass_socket, bool,
|
||||||
|
private_kernel_netlink_ipsec_t *this, int fd, int family)
|
||||||
|
{
|
||||||
|
struct xfrm_userpolicy_info policy;
|
||||||
|
u_int sol, ipsec_policy;
|
||||||
|
|
||||||
|
switch (family)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
sol = SOL_IP;
|
||||||
|
ipsec_policy = IP_XFRM_POLICY;
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
sol = SOL_IPV6;
|
||||||
|
ipsec_policy = IPV6_XFRM_POLICY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&policy, 0, sizeof(policy));
|
||||||
|
policy.action = XFRM_POLICY_ALLOW;
|
||||||
|
policy.sel.family = family;
|
||||||
|
|
||||||
|
policy.dir = XFRM_POLICY_OUT;
|
||||||
|
if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
|
||||||
|
{
|
||||||
|
DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
|
||||||
|
strerror(errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
policy.dir = XFRM_POLICY_IN;
|
||||||
|
if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
|
||||||
|
{
|
||||||
|
DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
|
||||||
|
strerror(errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(kernel_ipsec_t, destroy, void,
|
METHOD(kernel_ipsec_t, destroy, void,
|
||||||
private_kernel_netlink_ipsec_t *this)
|
private_kernel_netlink_ipsec_t *this)
|
||||||
{
|
{
|
||||||
@@ -1912,60 +1953,6 @@ METHOD(kernel_ipsec_t, destroy, void,
|
|||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add bypass policies for IKE on the sockets used by charon
|
|
||||||
*/
|
|
||||||
static bool add_bypass_policies()
|
|
||||||
{
|
|
||||||
int fd, family, port;
|
|
||||||
enumerator_t *sockets;
|
|
||||||
bool status = TRUE;
|
|
||||||
|
|
||||||
sockets = charon->socket->create_enumerator(charon->socket);
|
|
||||||
while (sockets->enumerate(sockets, &fd, &family, &port))
|
|
||||||
{
|
|
||||||
struct xfrm_userpolicy_info policy;
|
|
||||||
u_int sol, ipsec_policy;
|
|
||||||
|
|
||||||
switch (family)
|
|
||||||
{
|
|
||||||
case AF_INET:
|
|
||||||
sol = SOL_IP;
|
|
||||||
ipsec_policy = IP_XFRM_POLICY;
|
|
||||||
break;
|
|
||||||
case AF_INET6:
|
|
||||||
sol = SOL_IPV6;
|
|
||||||
ipsec_policy = IPV6_XFRM_POLICY;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&policy, 0, sizeof(policy));
|
|
||||||
policy.action = XFRM_POLICY_ALLOW;
|
|
||||||
policy.sel.family = family;
|
|
||||||
|
|
||||||
policy.dir = XFRM_POLICY_OUT;
|
|
||||||
if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
|
|
||||||
{
|
|
||||||
DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
|
|
||||||
strerror(errno));
|
|
||||||
status = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
policy.dir = XFRM_POLICY_IN;
|
|
||||||
if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
|
|
||||||
{
|
|
||||||
DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
|
|
||||||
strerror(errno));
|
|
||||||
status = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sockets->destroy(sockets);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Described in header.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
@@ -1986,6 +1973,7 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
|
|||||||
.add_policy = _add_policy,
|
.add_policy = _add_policy,
|
||||||
.query_policy = _query_policy,
|
.query_policy = _query_policy,
|
||||||
.del_policy = _del_policy,
|
.del_policy = _del_policy,
|
||||||
|
.bypass_socket = _bypass_socket,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.policies = hashtable_create((hashtable_hash_t)policy_hash,
|
.policies = hashtable_create((hashtable_hash_t)policy_hash,
|
||||||
@@ -2020,13 +2008,6 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
|
|||||||
{
|
{
|
||||||
charon->kill(charon, "unable to bind XFRM event socket");
|
charon->kill(charon, "unable to bind XFRM event socket");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add bypass policies on the sockets used by charon */
|
|
||||||
if (!add_bypass_policies())
|
|
||||||
{
|
|
||||||
charon->kill(charon, "unable to add bypass policies on sockets");
|
|
||||||
}
|
|
||||||
|
|
||||||
this->job = callback_job_create((callback_job_cb_t)receive_events,
|
this->job = callback_job_create((callback_job_cb_t)receive_events,
|
||||||
this, NULL, NULL);
|
this, NULL, NULL);
|
||||||
charon->processor->queue_job(charon->processor, (job_t*)this->job);
|
charon->processor->queue_job(charon->processor, (job_t*)this->job);
|
||||||
|
|||||||
@@ -2044,6 +2044,52 @@ static status_t register_pfkey_socket(private_kernel_pfkey_ipsec_t *this,
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(kernel_ipsec_t, bypass_socket, bool,
|
||||||
|
private_kernel_pfkey_ipsec_t *this, int fd, int family)
|
||||||
|
{
|
||||||
|
struct sadb_x_policy policy;
|
||||||
|
u_int sol, ipsec_policy;
|
||||||
|
|
||||||
|
switch (family)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
{
|
||||||
|
sol = SOL_IP;
|
||||||
|
ipsec_policy = IP_IPSEC_POLICY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AF_INET6:
|
||||||
|
{
|
||||||
|
sol = SOL_IPV6;
|
||||||
|
ipsec_policy = IPV6_IPSEC_POLICY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&policy, 0, sizeof(policy));
|
||||||
|
policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t);
|
||||||
|
policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
|
||||||
|
policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
|
||||||
|
|
||||||
|
policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
|
||||||
|
if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
|
||||||
|
{
|
||||||
|
DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
|
||||||
|
strerror(errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
|
||||||
|
if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
|
||||||
|
{
|
||||||
|
DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
|
||||||
|
strerror(errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(kernel_ipsec_t, destroy, void,
|
METHOD(kernel_ipsec_t, destroy, void,
|
||||||
private_kernel_pfkey_ipsec_t *this)
|
private_kernel_pfkey_ipsec_t *this)
|
||||||
{
|
{
|
||||||
@@ -2056,65 +2102,6 @@ METHOD(kernel_ipsec_t, destroy, void,
|
|||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add bypass policies for IKE on the sockets of charon
|
|
||||||
*/
|
|
||||||
static bool add_bypass_policies(private_kernel_pfkey_ipsec_t *this)
|
|
||||||
{
|
|
||||||
int fd, family, port;
|
|
||||||
enumerator_t *sockets;
|
|
||||||
bool status = TRUE;
|
|
||||||
|
|
||||||
sockets = charon->socket->create_enumerator(charon->socket);
|
|
||||||
while (sockets->enumerate(sockets, &fd, &family, &port))
|
|
||||||
{
|
|
||||||
struct sadb_x_policy policy;
|
|
||||||
u_int sol, ipsec_policy;
|
|
||||||
|
|
||||||
switch (family)
|
|
||||||
{
|
|
||||||
case AF_INET:
|
|
||||||
{
|
|
||||||
sol = SOL_IP;
|
|
||||||
ipsec_policy = IP_IPSEC_POLICY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AF_INET6:
|
|
||||||
{
|
|
||||||
sol = SOL_IPV6;
|
|
||||||
ipsec_policy = IPV6_IPSEC_POLICY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&policy, 0, sizeof(policy));
|
|
||||||
policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t);
|
|
||||||
policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
|
|
||||||
policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
|
|
||||||
|
|
||||||
policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
|
|
||||||
if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
|
|
||||||
{
|
|
||||||
DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
|
|
||||||
strerror(errno));
|
|
||||||
status = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
|
|
||||||
if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
|
|
||||||
{
|
|
||||||
DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
|
|
||||||
strerror(errno));
|
|
||||||
status = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sockets->destroy(sockets);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Described in header.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
@@ -2133,6 +2120,7 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create()
|
|||||||
.add_policy = _add_policy,
|
.add_policy = _add_policy,
|
||||||
.query_policy = _query_policy,
|
.query_policy = _query_policy,
|
||||||
.del_policy = _del_policy,
|
.del_policy = _del_policy,
|
||||||
|
.bypass_socket = _bypass_socket,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.policies = linked_list_create(),
|
.policies = linked_list_create(),
|
||||||
@@ -2156,12 +2144,6 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create()
|
|||||||
charon->kill(charon, "unable to create PF_KEY event socket");
|
charon->kill(charon, "unable to create PF_KEY event socket");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add bypass policies on the sockets used by charon */
|
|
||||||
if (!add_bypass_policies(this))
|
|
||||||
{
|
|
||||||
charon->kill(charon, "unable to add bypass policies on sockets");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* register the event socket */
|
/* register the event socket */
|
||||||
if (register_pfkey_socket(this, SADB_SATYPE_ESP) != SUCCESS ||
|
if (register_pfkey_socket(this, SADB_SATYPE_ESP) != SUCCESS ||
|
||||||
register_pfkey_socket(this, SADB_SATYPE_AH) != SUCCESS)
|
register_pfkey_socket(this, SADB_SATYPE_AH) != SUCCESS)
|
||||||
|
|||||||
@@ -521,6 +521,12 @@ static int open_socket(private_socket_default_socket_t *this,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!charon->kernel_interface->bypass_socket(charon->kernel_interface,
|
||||||
|
skt, family))
|
||||||
|
{
|
||||||
|
DBG1(DBG_NET, "installing IKE bypass policy failed");
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
{
|
{
|
||||||
/* enable UDP decapsulation globally, only for one socket needed */
|
/* enable UDP decapsulation globally, only for one socket needed */
|
||||||
@@ -535,66 +541,6 @@ static int open_socket(private_socket_default_socket_t *this,
|
|||||||
return skt;
|
return skt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* enumerator for underlying sockets
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
/** implements enumerator_t */
|
|
||||||
enumerator_t public;
|
|
||||||
/** sockets we enumerate */
|
|
||||||
private_socket_default_socket_t *socket;
|
|
||||||
/** counter */
|
|
||||||
int index;
|
|
||||||
} socket_enumerator_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* enumerate function for socket_enumerator_t
|
|
||||||
*/
|
|
||||||
static bool enumerate(socket_enumerator_t *this, int *fd, int *family, int *port)
|
|
||||||
{
|
|
||||||
static const struct {
|
|
||||||
int fd_offset;
|
|
||||||
int family;
|
|
||||||
int port;
|
|
||||||
} sockets[] = {
|
|
||||||
{ offsetof(private_socket_default_socket_t, ipv4),
|
|
||||||
AF_INET, IKEV2_UDP_PORT },
|
|
||||||
{ offsetof(private_socket_default_socket_t, ipv6),
|
|
||||||
AF_INET6, IKEV2_UDP_PORT },
|
|
||||||
{ offsetof(private_socket_default_socket_t, ipv4_natt),
|
|
||||||
AF_INET, IKEV2_NATT_PORT },
|
|
||||||
{ offsetof(private_socket_default_socket_t, ipv6_natt),
|
|
||||||
AF_INET6, IKEV2_NATT_PORT }
|
|
||||||
};
|
|
||||||
|
|
||||||
while(++this->index < countof(sockets))
|
|
||||||
{
|
|
||||||
int sock = *(int*)((char*)this->socket + sockets[this->index].fd_offset);
|
|
||||||
if (!sock)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*fd = sock;
|
|
||||||
*family = sockets[this->index].family;
|
|
||||||
*port = sockets[this->index].port;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(socket_t, create_enumerator, enumerator_t*,
|
|
||||||
private_socket_default_socket_t *this)
|
|
||||||
{
|
|
||||||
socket_enumerator_t *enumerator;
|
|
||||||
|
|
||||||
enumerator = malloc_thing(socket_enumerator_t);
|
|
||||||
enumerator->index = -1;
|
|
||||||
enumerator->socket = this;
|
|
||||||
enumerator->public.enumerate = (void*)enumerate;
|
|
||||||
enumerator->public.destroy = (void*)free;
|
|
||||||
return &enumerator->public;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(socket_default_socket_t, destroy, void,
|
METHOD(socket_default_socket_t, destroy, void,
|
||||||
private_socket_default_socket_t *this)
|
private_socket_default_socket_t *this)
|
||||||
{
|
{
|
||||||
@@ -629,7 +575,6 @@ socket_default_socket_t *socket_default_socket_create()
|
|||||||
.socket = {
|
.socket = {
|
||||||
.send = _sender,
|
.send = _sender,
|
||||||
.receive = _receiver,
|
.receive = _receiver,
|
||||||
.create_enumerator = _create_enumerator,
|
|
||||||
},
|
},
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -492,6 +492,12 @@ static int open_send_socket(private_socket_raw_socket_t *this,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!charon->kernel_interface->bypass_socket(charon->kernel_interface,
|
||||||
|
skt, family))
|
||||||
|
{
|
||||||
|
DBG1(DBG_NET, "installing bypass policy on send socket failed");
|
||||||
|
}
|
||||||
|
|
||||||
return skt;
|
return skt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,65 +596,13 @@ static int open_recv_socket(private_socket_raw_socket_t *this, int family)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return skt;
|
if (!charon->kernel_interface->bypass_socket(charon->kernel_interface,
|
||||||
}
|
skt, family))
|
||||||
|
|
||||||
/**
|
|
||||||
* enumerator for underlying sockets
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
/** implements enumerator_t */
|
|
||||||
enumerator_t public;
|
|
||||||
/** sockets we enumerate */
|
|
||||||
private_socket_raw_socket_t *socket;
|
|
||||||
/** counter */
|
|
||||||
int index;
|
|
||||||
} socket_enumerator_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* enumerate function for socket_enumerator_t
|
|
||||||
*/
|
|
||||||
static bool enumerate(socket_enumerator_t *this, int *fd, int *family, int *port)
|
|
||||||
{
|
|
||||||
static const struct {
|
|
||||||
int fd_offset;
|
|
||||||
int family;
|
|
||||||
int port;
|
|
||||||
} sockets[] = {
|
|
||||||
{ offsetof(private_socket_raw_socket_t, recv4), AF_INET, IKEV2_UDP_PORT },
|
|
||||||
{ offsetof(private_socket_raw_socket_t, recv6), AF_INET6, IKEV2_UDP_PORT },
|
|
||||||
{ offsetof(private_socket_raw_socket_t, send4), AF_INET, IKEV2_UDP_PORT },
|
|
||||||
{ offsetof(private_socket_raw_socket_t, send6), AF_INET6, IKEV2_UDP_PORT },
|
|
||||||
{ offsetof(private_socket_raw_socket_t, send4_natt), AF_INET, IKEV2_NATT_PORT },
|
|
||||||
{ offsetof(private_socket_raw_socket_t, send6_natt), AF_INET6, IKEV2_NATT_PORT }
|
|
||||||
};
|
|
||||||
|
|
||||||
while(++this->index < countof(sockets))
|
|
||||||
{
|
{
|
||||||
int sock = *(int*)((char*)this->socket + sockets[this->index].fd_offset);
|
DBG1(DBG_NET, "installing bypass policy on receive socket failed");
|
||||||
if (!sock)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*fd = sock;
|
|
||||||
*family = sockets[this->index].family;
|
|
||||||
*port = sockets[this->index].port;
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(socket_t, create_enumerator, enumerator_t*,
|
return skt;
|
||||||
private_socket_raw_socket_t *this)
|
|
||||||
{
|
|
||||||
socket_enumerator_t *enumerator;
|
|
||||||
|
|
||||||
enumerator = malloc_thing(socket_enumerator_t);
|
|
||||||
enumerator->index = -1;
|
|
||||||
enumerator->socket = this;
|
|
||||||
enumerator->public.enumerate = (void*)enumerate;
|
|
||||||
enumerator->public.destroy = (void*)free;
|
|
||||||
return &enumerator->public;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(socket_raw_socket_t, destroy, void,
|
METHOD(socket_raw_socket_t, destroy, void,
|
||||||
@@ -693,7 +647,6 @@ socket_raw_socket_t *socket_raw_socket_create()
|
|||||||
.socket = {
|
.socket = {
|
||||||
.send = _sender,
|
.send = _sender,
|
||||||
.receive = _receiver,
|
.receive = _receiver,
|
||||||
.create_enumerator = _create_enumerator,
|
|
||||||
},
|
},
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user