-/* $OpenBSD: radiusctl.c,v 1.10 2024/07/14 11:12:32 yasuoka Exp $ */
+/* $OpenBSD: radiusctl.c,v 1.11 2024/07/22 09:39:23 yasuoka Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
*
iov[niov++].iov_len = sizeof(res->session_seq);
imsg_composev(&ibuf, IMSG_RADIUSD_MODULE_IPCP_DISCONNECT, 0, 0,
-1, iov, niov);
- done = 1;
break;
}
while (ibuf.w.queued) {
case IPCP_SHOW:
case IPCP_DUMP:
case IPCP_MONITOR:
+ case IPCP_DISCONNECT:
done = ipcp_handle_imsg(res, &imsg, cnt++);
break;
default:
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
switch (imsg->hdr.type) {
+ case IMSG_OK:
+ if (datalen > 0 && *((char *)imsg->data + datalen - 1) == '\0')
+ fprintf(stderr, "OK: %s\n", (char *)imsg->data);
+ else
+ fprintf(stderr, "OK\n");
+ done = 1;
+ break;
case IMSG_NG:
if (datalen > 0 && *((char *)imsg->data + datalen - 1) == '\0')
fprintf(stderr, "error: %s\n", (char *)imsg->data);
-/* $OpenBSD: radiusd_ipcp.c,v 1.5 2024/07/17 11:31:46 yasuoka Exp $ */
+/* $OpenBSD: radiusd_ipcp.c,v 1.6 2024/07/22 09:39:23 yasuoka Exp $ */
/*
* Copyright (c) 2024 Internet Initiative Japan Inc.
char name[0];
};
+struct radiusctl_client {
+ int peerid;
+ TAILQ_ENTRY(radiusctl_client) entry;
+};
+
struct module_ipcp_dae;
struct assigned_ipv4 {
TAILQ_ENTRY(assigned_ipv4) dae_next;
int dae_ntry;
struct event dae_evtimer;
+ TAILQ_HEAD(, radiusctl_client) dae_clients;
};
struct module_ipcp_ctrlconn {
*dae0 = dae;
TAILQ_INIT(&dae0->reqs);
TAILQ_INSERT_TAIL(&module->daes, dae0, next);
+ dae0->ipcp = module;
} else if (strcmp(name, "_debug") == 0)
log_init(1);
else if (strncmp(name, "_", 1) == 0)
size_t dumpsiz;
u_int datalen;
unsigned seq;
+ struct radiusctl_client *client;
+ const char *cause;
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
switch (imsg->hdr.type) {
if (assign->seq == seq)
break;
}
- if (assign == NULL)
+ if (assign == NULL) {
+ cause = "session not found";
log_warnx("Disconnect seq=%u requested, but the "
"session is not found", seq);
+ module_imsg_compose(self->base, IMSG_NG,
+ imsg->hdr.peerid, 0, -1, cause, strlen(cause) + 1);
+ }
else {
if (assign->dae == NULL)
log_warnx("Disconnect seq=%u requested, but "
else {
log_info("Disconnect seq=%u requested",
assign->seq);
+ if ((client = calloc(1, sizeof(struct
+ radiusctl_client))) == NULL) {
+ log_warn("%s: calloc: %m",
+ __func__);
+ goto fail;
+ }
+ client->peerid = imsg->hdr.peerid;
if (assign->dae_ntry == 0)
ipcp_dae_send_disconnect_request(
assign);
+ TAILQ_INSERT_TAIL(&assign->dae_clients,
+ client, entry);
}
}
break;
ip->authtime = self->uptime;
RB_INSERT(assigned_ipv4_tree, &self->ipv4s, ip);
TAILQ_INSERT_TAIL(&user->ipv4s, ip, next);
+ TAILQ_INIT(&ip->dae_clients);
self->nsessions++;
ip->seq = self->seq++;
ipcp_dae_on_event(int fd, short ev, void *ctx)
{
struct module_ipcp_dae *dae = ctx;
+ struct module_ipcp *self = dae->ipcp;
RADIUS_PACKET *radres = NULL;
int code;
uint32_t u32;
struct assigned_ipv4 *assign;
char buf[80], causestr[80];
const char *cause = "";
+ struct radiusctl_client *client;
if ((ev & EV_READ) == 0)
return;
&dae->nas_addr, buf, sizeof(buf)));
break;
}
+
+ TAILQ_FOREACH(client, &assign->dae_clients, entry) {
+ if (*cause != '\0')
+ module_imsg_compose(self->base,
+ (code == RADIUS_CODE_DISCONNECT_ACK)
+ ? IMSG_OK : IMSG_NG, client->peerid, 0, -1,
+ cause + 1, strlen(cause + 1) + 1);
+ else
+ module_imsg_compose(self->base,
+ (code == RADIUS_CODE_DISCONNECT_ACK)
+ ? IMSG_OK : IMSG_NG, client->peerid, 0, -1,
+ NULL, 0);
+ }
ipcp_dae_reset_request(assign);
out:
if (radres != NULL)
void
ipcp_dae_reset_request(struct assigned_ipv4 *assign)
{
+ struct radiusctl_client *client, *clientt;
+
if (assign->dae != NULL) {
if (assign->dae_ntry > 0)
TAILQ_REMOVE(&assign->dae->reqs, assign, dae_next);
assign->dae_reqpkt = NULL;
if (evtimer_pending(&assign->dae_evtimer, NULL))
evtimer_del(&assign->dae_evtimer);
+ TAILQ_FOREACH_SAFE(client, &assign->dae_clients, entry, clientt) {
+ TAILQ_REMOVE(&assign->dae_clients, client, entry);
+ free(client);
+ }
assign->dae_ntry = 0;
}