tnc-pdp now uses watcher_t
This commit is contained in:
@@ -450,102 +450,61 @@ end:
|
|||||||
/**
|
/**
|
||||||
* Process packets received on the RADIUS socket
|
* Process packets received on the RADIUS socket
|
||||||
*/
|
*/
|
||||||
static job_requeue_t receive(private_tnc_pdp_t *this)
|
static bool receive(private_tnc_pdp_t *this, int fd, watcher_event_t event)
|
||||||
{
|
{
|
||||||
while (TRUE)
|
radius_message_t *request;
|
||||||
|
char buffer[MAX_PACKET];
|
||||||
|
int bytes_read = 0;
|
||||||
|
host_t *source;
|
||||||
|
struct msghdr msg;
|
||||||
|
struct iovec iov;
|
||||||
|
union {
|
||||||
|
struct sockaddr_in in4;
|
||||||
|
struct sockaddr_in6 in6;
|
||||||
|
} src;
|
||||||
|
|
||||||
|
/* read received packet */
|
||||||
|
msg.msg_name = &src;
|
||||||
|
msg.msg_namelen = sizeof(src);
|
||||||
|
iov.iov_base = buffer;
|
||||||
|
iov.iov_len = MAX_PACKET;
|
||||||
|
msg.msg_iov = &iov;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
msg.msg_flags = 0;
|
||||||
|
|
||||||
|
bytes_read = recvmsg(fd, &msg, 0);
|
||||||
|
if (bytes_read < 0)
|
||||||
{
|
{
|
||||||
radius_message_t *request;
|
DBG1(DBG_CFG, "error reading RADIUS socket: %s", strerror(errno));
|
||||||
char buffer[MAX_PACKET];
|
return FALSE;
|
||||||
int max_fd = 0, selected = 0, bytes_read = 0;
|
|
||||||
fd_set rfds;
|
|
||||||
bool oldstate;
|
|
||||||
host_t *source;
|
|
||||||
struct msghdr msg;
|
|
||||||
struct iovec iov;
|
|
||||||
union {
|
|
||||||
struct sockaddr_in in4;
|
|
||||||
struct sockaddr_in6 in6;
|
|
||||||
} src;
|
|
||||||
|
|
||||||
FD_ZERO(&rfds);
|
|
||||||
|
|
||||||
if (this->ipv4)
|
|
||||||
{
|
|
||||||
FD_SET(this->ipv4, &rfds);
|
|
||||||
}
|
|
||||||
if (this->ipv6)
|
|
||||||
{
|
|
||||||
FD_SET(this->ipv6, &rfds);
|
|
||||||
}
|
|
||||||
max_fd = max(this->ipv4, this->ipv6);
|
|
||||||
|
|
||||||
DBG2(DBG_CFG, "waiting for data on RADIUS sockets");
|
|
||||||
oldstate = thread_cancelability(TRUE);
|
|
||||||
if (select(max_fd + 1, &rfds, NULL, NULL, NULL) <= 0)
|
|
||||||
{
|
|
||||||
thread_cancelability(oldstate);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
thread_cancelability(oldstate);
|
|
||||||
|
|
||||||
if (FD_ISSET(this->ipv4, &rfds))
|
|
||||||
{
|
|
||||||
selected = this->ipv4;
|
|
||||||
}
|
|
||||||
else if (FD_ISSET(this->ipv6, &rfds))
|
|
||||||
{
|
|
||||||
selected = this->ipv6;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* oops, shouldn't happen */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read received packet */
|
|
||||||
msg.msg_name = &src;
|
|
||||||
msg.msg_namelen = sizeof(src);
|
|
||||||
iov.iov_base = buffer;
|
|
||||||
iov.iov_len = MAX_PACKET;
|
|
||||||
msg.msg_iov = &iov;
|
|
||||||
msg.msg_iovlen = 1;
|
|
||||||
msg.msg_flags = 0;
|
|
||||||
|
|
||||||
bytes_read = recvmsg(selected, &msg, 0);
|
|
||||||
if (bytes_read < 0)
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, "error reading RADIUS socket: %s", strerror(errno));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (msg.msg_flags & MSG_TRUNC)
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, "receive buffer too small, RADIUS packet discarded");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
source = host_create_from_sockaddr((sockaddr_t*)&src);
|
|
||||||
DBG2(DBG_CFG, "received RADIUS packet from %#H", source);
|
|
||||||
DBG3(DBG_CFG, "%b", buffer, bytes_read);
|
|
||||||
request = radius_message_parse(chunk_create(buffer, bytes_read));
|
|
||||||
if (request)
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, "received RADIUS %N from client '%H'",
|
|
||||||
radius_message_code_names, request->get_code(request), source);
|
|
||||||
|
|
||||||
if (request->verify(request, NULL, this->secret, this->hasher,
|
|
||||||
this->signer))
|
|
||||||
{
|
|
||||||
process_eap(this, request, source);
|
|
||||||
}
|
|
||||||
request->destroy(request);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, "received invalid RADIUS message, ignored");
|
|
||||||
}
|
|
||||||
source->destroy(source);
|
|
||||||
}
|
}
|
||||||
return JOB_REQUEUE_FAIR;
|
if (msg.msg_flags & MSG_TRUNC)
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "receive buffer too small, RADIUS packet discarded");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
source = host_create_from_sockaddr((sockaddr_t*)&src);
|
||||||
|
DBG2(DBG_CFG, "received RADIUS packet from %#H", source);
|
||||||
|
DBG3(DBG_CFG, "%b", buffer, bytes_read);
|
||||||
|
request = radius_message_parse(chunk_create(buffer, bytes_read));
|
||||||
|
if (request)
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "received RADIUS %N from client '%H'",
|
||||||
|
radius_message_code_names, request->get_code(request), source);
|
||||||
|
|
||||||
|
if (request->verify(request, NULL, this->secret, this->hasher,
|
||||||
|
this->signer))
|
||||||
|
{
|
||||||
|
process_eap(this, request, source);
|
||||||
|
}
|
||||||
|
request->destroy(request);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "received invalid RADIUS message, ignored");
|
||||||
|
}
|
||||||
|
source->destroy(source);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(tnc_pdp_t, destroy, void,
|
METHOD(tnc_pdp_t, destroy, void,
|
||||||
@@ -553,10 +512,12 @@ METHOD(tnc_pdp_t, destroy, void,
|
|||||||
{
|
{
|
||||||
if (this->ipv4)
|
if (this->ipv4)
|
||||||
{
|
{
|
||||||
|
lib->watcher->remove(lib->watcher, this->ipv4);
|
||||||
close(this->ipv4);
|
close(this->ipv4);
|
||||||
}
|
}
|
||||||
if (this->ipv6)
|
if (this->ipv6)
|
||||||
{
|
{
|
||||||
|
lib->watcher->remove(lib->watcher, this->ipv6);
|
||||||
close(this->ipv6);
|
close(this->ipv6);
|
||||||
}
|
}
|
||||||
DESTROY_IF(this->server);
|
DESTROY_IF(this->server);
|
||||||
@@ -599,11 +560,21 @@ tnc_pdp_t *tnc_pdp_create(u_int16_t port)
|
|||||||
destroy(this);
|
destroy(this);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!this->ipv4)
|
if (this->ipv4)
|
||||||
|
{
|
||||||
|
lib->watcher->add(lib->watcher, this->ipv4, WATCHER_READ,
|
||||||
|
(watcher_cb_t)receive, this);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
DBG1(DBG_NET, "could not open IPv4 RADIUS socket, IPv4 disabled");
|
DBG1(DBG_NET, "could not open IPv4 RADIUS socket, IPv4 disabled");
|
||||||
}
|
}
|
||||||
if (!this->ipv6)
|
if (this->ipv6)
|
||||||
|
{
|
||||||
|
lib->watcher->add(lib->watcher, this->ipv6, WATCHER_READ,
|
||||||
|
(watcher_cb_t)receive, this);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
DBG1(DBG_NET, "could not open IPv6 RADIUS socket, IPv6 disabled");
|
DBG1(DBG_NET, "could not open IPv6 RADIUS socket, IPv6 disabled");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user