mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-04 00:00:14 -04:00
dhcp: Don't use get_source_addr() to determine source address
That method is subject to interface filtering, which isn't ideal for DHCP traffic that probably uses an internal interface on which the IKE daemon might be disabled. In that case `giaddr` is set to an incorrect public IP, which in turn might prevent the plugin from receiving the DHCP server's unicast response, in particular if the DHCP socket is bound to the internal interface. This new approach connects the client socket and thereby determines the source address to reach the DHCP server. Closes strongswan/strongswan#1573
This commit is contained in:
parent
8bf683c469
commit
3c8887326a
@ -111,6 +111,11 @@ struct private_dhcp_socket_t {
|
||||
* Force configured destination address
|
||||
*/
|
||||
bool force_dst;
|
||||
|
||||
/**
|
||||
* Source IP if destination address is unicast
|
||||
*/
|
||||
struct sockaddr_in src;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -202,7 +207,6 @@ static int prepare_dhcp(private_dhcp_socket_t *this,
|
||||
identification_t *identity;
|
||||
dhcp_option_t *option;
|
||||
int optlen = 0, remaining;
|
||||
host_t *src;
|
||||
uint32_t id;
|
||||
|
||||
memset(dhcp, 0, sizeof(*dhcp));
|
||||
@ -219,14 +223,8 @@ static int prepare_dhcp(private_dhcp_socket_t *this,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* act as relay agent */
|
||||
src = charon->kernel->get_source_addr(charon->kernel, this->dst, NULL);
|
||||
if (src)
|
||||
{
|
||||
memcpy(&dhcp->gateway_address, src->get_address(src).ptr,
|
||||
memcpy(&dhcp->gateway_address, &this->src.sin_addr,
|
||||
sizeof(dhcp->gateway_address));
|
||||
src->destroy(src);
|
||||
}
|
||||
}
|
||||
|
||||
identity = transaction->get_identity(transaction);
|
||||
@ -736,6 +734,7 @@ dhcp_socket_t *dhcp_socket_create()
|
||||
.s_addr = INADDR_ANY,
|
||||
},
|
||||
};
|
||||
socklen_t addr_len;
|
||||
char *iface;
|
||||
int on = 1, rcvbuf = 0;
|
||||
struct sock_filter dhcp_filter_code[] = {
|
||||
@ -888,6 +887,25 @@ dhcp_socket_t *dhcp_socket_create()
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (!is_broadcast(this->dst))
|
||||
{
|
||||
if (connect(this->send, this->dst->get_sockaddr(this->dst),
|
||||
*this->dst->get_sockaddr_len(this->dst)) < 0)
|
||||
{
|
||||
DBG1(DBG_CFG, "unable to connect DHCP send socket: %s",
|
||||
strerror(errno));
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
addr_len = sizeof(this->src);
|
||||
if (getsockname(this->send, &this->src, &addr_len) < 0)
|
||||
{
|
||||
DBG1(DBG_CFG, "unable to determine source address for DHCP: %s",
|
||||
strerror(errno));
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
lib->watcher->add(lib->watcher, this->receive, WATCHER_READ,
|
||||
(watcher_cb_t)receive_dhcp, this);
|
||||
|
Loading…
x
Reference in New Issue
Block a user