summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/dhcp/dhcp_socket.c
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2013-10-17 21:23:38 +0200
committerYves-Alexis Perez <corsac@debian.org>2013-10-17 21:23:38 +0200
commit9d37ad77ef660b92ea51b69d74e14f931d2a04e2 (patch)
treed6bbb4a5fed1959f8675df9ee7c03713b543fcc9 /src/libcharon/plugins/dhcp/dhcp_socket.c
parent104f57d4b0fb6d7547d6898352eaa5fb4b222010 (diff)
parente5ee4e7fcdd58b7d86bf1b458da2c63e8e19627b (diff)
downloadvyos-strongswan-9d37ad77ef660b92ea51b69d74e14f931d2a04e2.tar.gz
vyos-strongswan-9d37ad77ef660b92ea51b69d74e14f931d2a04e2.zip
Merge tag 'v5.1.0-1' into sid
tag strongSwan 5.1.0-1
Diffstat (limited to 'src/libcharon/plugins/dhcp/dhcp_socket.c')
-rw-r--r--src/libcharon/plugins/dhcp/dhcp_socket.c59
1 files changed, 32 insertions, 27 deletions
diff --git a/src/libcharon/plugins/dhcp/dhcp_socket.c b/src/libcharon/plugins/dhcp/dhcp_socket.c
index 5d98e5b8d..044c8a819 100644
--- a/src/libcharon/plugins/dhcp/dhcp_socket.c
+++ b/src/libcharon/plugins/dhcp/dhcp_socket.c
@@ -25,7 +25,7 @@
#include <linux/if_ether.h>
#include <linux/filter.h>
-#include <utils/linked_list.h>
+#include <collections/linked_list.h>
#include <utils/identification.h>
#include <threading/mutex.h>
#include <threading/condvar.h>
@@ -107,9 +107,9 @@ struct private_dhcp_socket_t {
host_t *dst;
/**
- * Callback job receiving DHCP responses
+ * Force configured destination address
*/
- callback_job_t *job;
+ bool force_dst;
};
/**
@@ -227,7 +227,7 @@ static int prepare_dhcp(private_dhcp_socket_t *this,
/* with ID specific postfix */
if (this->identity_lease)
{
- id = htonl(chunk_hash(chunk));
+ id = htonl(chunk_hash_static(chunk));
}
else
{
@@ -271,7 +271,7 @@ static bool send_dhcp(private_dhcp_socket_t *this,
ssize_t len;
dst = transaction->get_server(transaction);
- if (!dst)
+ if (!dst || this->force_dst)
{
dst = this->dst;
}
@@ -371,7 +371,11 @@ METHOD(dhcp_socket_t, enroll, dhcp_transaction_t*,
u_int32_t id;
int try;
- this->rng->get_bytes(this->rng, sizeof(id), (u_int8_t*)&id);
+ if (!this->rng->get_bytes(this->rng, sizeof(id), (u_int8_t*)&id))
+ {
+ DBG1(DBG_CFG, "DHCP DISCOVER failed, no transaction ID");
+ return NULL;
+ }
transaction = dhcp_transaction_create(id, identity);
this->mutex->lock(this->mutex);
@@ -558,7 +562,8 @@ static void handle_ack(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen)
/**
* Receive DHCP responses
*/
-static job_requeue_t receive_dhcp(private_dhcp_socket_t *this)
+static bool receive_dhcp(private_dhcp_socket_t *this, int fd,
+ watcher_event_t event)
{
struct sockaddr_ll addr;
socklen_t addr_len = sizeof(addr);
@@ -567,14 +572,12 @@ static job_requeue_t receive_dhcp(private_dhcp_socket_t *this)
struct udphdr udp;
dhcp_t dhcp;
} packet;
- int oldstate, optlen, origoptlen, optsize, optpos = 0;
+ int optlen, origoptlen, optsize, optpos = 0;
ssize_t len;
dhcp_option_t *option;
- oldstate = thread_cancelability(TRUE);
- len = recvfrom(this->receive, &packet, sizeof(packet), 0,
+ len = recvfrom(fd, &packet, sizeof(packet), MSG_DONTWAIT,
(struct sockaddr*)&addr, &addr_len);
- thread_cancelability(oldstate);
if (len >= sizeof(struct iphdr) + sizeof(struct udphdr) +
offsetof(dhcp_t, options))
@@ -607,16 +610,12 @@ static job_requeue_t receive_dhcp(private_dhcp_socket_t *this)
optpos += optsize;
}
}
- return JOB_REQUEUE_DIRECT;
+ return TRUE;
}
METHOD(dhcp_socket_t, destroy, void,
private_dhcp_socket_t *this)
{
- if (this->job)
- {
- this->job->cancel(this->job);
- }
while (this->waiting)
{
this->condvar->signal(this->condvar);
@@ -627,6 +626,7 @@ METHOD(dhcp_socket_t, destroy, void,
}
if (this->receive > 0)
{
+ lib->watcher->remove(lib->watcher, this->receive);
close(this->receive);
}
this->mutex->destroy(this->mutex);
@@ -648,7 +648,13 @@ METHOD(dhcp_socket_t, destroy, void,
dhcp_socket_t *dhcp_socket_create()
{
private_dhcp_socket_t *this;
- struct sockaddr_in src;
+ struct sockaddr_in src = {
+ .sin_family = AF_INET,
+ .sin_port = htons(DHCP_CLIENT_PORT),
+ .sin_addr = {
+ .s_addr = INADDR_ANY,
+ },
+ };
int on = 1;
struct sock_filter dhcp_filter_code[] = {
BPF_STMT(BPF_LD+BPF_B+BPF_ABS,
@@ -704,10 +710,14 @@ dhcp_socket_t *dhcp_socket_create()
return NULL;
}
this->identity_lease = lib->settings->get_bool(lib->settings,
- "charon.plugins.dhcp.identity_lease", FALSE);
+ "%s.plugins.dhcp.identity_lease", FALSE,
+ charon->name);
+ this->force_dst = lib->settings->get_str(lib->settings,
+ "%s.plugins.dhcp.force_server_address", FALSE,
+ charon->name);
this->dst = host_create_from_string(lib->settings->get_str(lib->settings,
- "charon.plugins.dhcp.server", "255.255.255.255"),
- DHCP_SERVER_PORT);
+ "%s.plugins.dhcp.server", "255.255.255.255",
+ charon->name), DHCP_SERVER_PORT);
if (!this->dst)
{
DBG1(DBG_CFG, "configured DHCP server address invalid");
@@ -734,9 +744,6 @@ dhcp_socket_t *dhcp_socket_create()
destroy(this);
return NULL;
}
- src.sin_family = AF_INET;
- src.sin_port = htons(DHCP_CLIENT_PORT);
- src.sin_addr.s_addr = INADDR_ANY;
if (bind(this->send, (struct sockaddr*)&src, sizeof(src)) == -1)
{
DBG1(DBG_CFG, "unable to bind DHCP send socket: %s", strerror(errno));
@@ -760,10 +767,8 @@ dhcp_socket_t *dhcp_socket_create()
return NULL;
}
- this->job = callback_job_create_with_prio((callback_job_cb_t)receive_dhcp,
- this, NULL, NULL, JOB_PRIO_CRITICAL);
- lib->processor->queue_job(lib->processor, (job_t*)this->job);
+ lib->watcher->add(lib->watcher, this->receive, WATCHER_READ,
+ (watcher_cb_t)receive_dhcp, this);
return &this->public;
}
-