summaryrefslogtreecommitdiff
path: root/accel-pppd/ctrl
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pppd/ctrl')
-rw-r--r--accel-pppd/ctrl/ipoe/arp.c6
-rw-r--r--accel-pppd/ctrl/ipoe/dhcpv4.c10
-rw-r--r--accel-pppd/ctrl/ipoe/dhcpv4_options.c37
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c226
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.h13
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe_netlink.c2
-rw-r--r--accel-pppd/ctrl/l2tp/CMakeLists.txt2
-rw-r--r--accel-pppd/ctrl/l2tp/l2tp.c291
-rw-r--r--accel-pppd/ctrl/l2tp/l2tp.h3
-rw-r--r--accel-pppd/ctrl/l2tp/packet.c7
-rw-r--r--accel-pppd/ctrl/pppoe/CMakeLists.txt7
-rw-r--r--accel-pppd/ctrl/pppoe/cli.c22
-rw-r--r--accel-pppd/ctrl/pppoe/disc.c7
-rw-r--r--accel-pppd/ctrl/pppoe/dpado.c36
-rw-r--r--accel-pppd/ctrl/pppoe/mac_filter.c16
-rw-r--r--accel-pppd/ctrl/pppoe/pppoe.c167
-rw-r--r--accel-pppd/ctrl/pppoe/pppoe.h33
-rw-r--r--accel-pppd/ctrl/pptp/pptp.c109
-rw-r--r--accel-pppd/ctrl/pptp/pptp.h7
-rw-r--r--accel-pppd/ctrl/sstp/CMakeLists.txt2
-rw-r--r--accel-pppd/ctrl/sstp/sstp.c236
-rw-r--r--accel-pppd/ctrl/sstp/sstp.h14
22 files changed, 797 insertions, 456 deletions
diff --git a/accel-pppd/ctrl/ipoe/arp.c b/accel-pppd/ctrl/ipoe/arp.c
index ef9d3859..a6ca5b13 100644
--- a/accel-pppd/ctrl/ipoe/arp.c
+++ b/accel-pppd/ctrl/ipoe/arp.c
@@ -13,10 +13,8 @@
#include <netinet/ip.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
-#ifdef HAVE_GOOD_IFARP
-#include <linux/if_arp.h>
-#endif
-#include <linux/if_packet.h>
+#include <net/if_arp.h>
+#include <netpacket/packet.h>
#include "list.h"
#include "triton.h"
diff --git a/accel-pppd/ctrl/ipoe/dhcpv4.c b/accel-pppd/ctrl/ipoe/dhcpv4.c
index 466dfee6..d80a80f3 100644
--- a/accel-pppd/ctrl/ipoe/dhcpv4.c
+++ b/accel-pppd/ctrl/ipoe/dhcpv4.c
@@ -161,7 +161,7 @@ struct dhcpv4_serv *dhcpv4_create(struct triton_context_t *ctx, const char *ifna
goto out_err;
}
- if (bind(sock, &addr, sizeof(addr))) {
+ if (bind(sock, (struct sockaddr*)&addr, sizeof(addr))) {
log_error("bind: %s\n", strerror(errno));
goto out_err;
}
@@ -356,9 +356,9 @@ static int dhcpv4_parse_packet(struct dhcpv4_packet *pack, int len)
else if (opt->type == 62)
pack->client_id = opt;
else if (opt->type == 50)
- pack->request_ip = *(uint32_t *)opt->data;
+ memcpy(&pack->request_ip, opt->data, 4);
else if (opt->type == 54)
- pack->server_id = *(uint32_t *)opt->data;
+ memcpy(&pack->server_id, opt->data, 4);
}
if (pack->msg_type == 0 || pack->msg_type > 8)
@@ -1012,12 +1012,12 @@ struct dhcpv4_relay *dhcpv4_relay_create(const char *_addr, in_addr_t giaddr, st
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &f, sizeof(f)))
log_error("dhcpv4: setsockopt(SO_REUSEADDR): %s\n", strerror(errno));
- if (bind(sock, &laddr, sizeof(laddr))) {
+ if (bind(sock, (struct sockaddr*)&laddr, sizeof(laddr))) {
log_error("dhcpv4: relay: %s: bind: %s\n", _addr, strerror(errno));
goto out_err_unlock;
}
- if (connect(sock, &raddr, sizeof(raddr))) {
+ if (connect(sock, (struct sockaddr*)&raddr, sizeof(raddr))) {
log_error("dhcpv4: relay: %s: connect: %s\n", _addr, strerror(errno));
goto out_err_unlock;
}
diff --git a/accel-pppd/ctrl/ipoe/dhcpv4_options.c b/accel-pppd/ctrl/ipoe/dhcpv4_options.c
index b5f2b3bf..bffcfa5c 100644
--- a/accel-pppd/ctrl/ipoe/dhcpv4_options.c
+++ b/accel-pppd/ctrl/ipoe/dhcpv4_options.c
@@ -46,7 +46,7 @@ static struct known_option options[] = {
{ 26, 2, 2, 2, "MTU", print_int },
{ 28, 4, 4, 4, "Broadcast", print_ip },
{ 33, 8, 255, 8, "Route", print_route },
- { 42, 4, 4, 4, "NTP", print_ip },
+ { 42, 4, 255, 4, "NTP", print_ip },
{ 43, 1, 255, 1, "Vendor-Specific", print_hex },
{ 50, 4, 4, 4, "Request-IP", print_ip },
{ 51, 4, 4, 4, "Lease-Time", print_uint },
@@ -113,18 +113,28 @@ void dhcpv4_print_options(struct dhcpv4_packet *pack, void (*print)(const char *
static void print_int(const struct dhcpv4_option *opt, int elem_size, void (*print)(const char *fmt, ...))
{
- if (opt->len == 2)
- print("%i", ntohs(*(int16_t *)(opt->data)));
- else
- print("%i", ntohl(*(int32_t *)(opt->data)));
+ if (opt->len == 2) {
+ int16_t val;
+ memcpy(&val, opt->data, sizeof(val));
+ print("%i", ntohs(val));
+ } else {
+ int32_t val;
+ memcpy(&val, opt->data, sizeof(val));
+ print("%i", ntohl(val));
+ }
}
static void print_uint(const struct dhcpv4_option *opt, int elem_size, void (*print)(const char *fmt, ...))
{
- if (opt->len == 2)
- print("%u", ntohs(*(uint16_t *)(opt->data)));
- else
- print("%u", ntohl(*(uint32_t *)(opt->data)));
+ if (opt->len == 2) {
+ uint16_t val;
+ memcpy(&val, opt->data, sizeof(val));
+ print("%u", ntohs(val));
+ } else {
+ uint32_t val;
+ memcpy(&val, opt->data, sizeof(val));
+ print("%u", ntohl(val));
+ }
}
static void print_ip(const struct dhcpv4_option *opt, int elem_size, void (*print)(const char *fmt, ...))
@@ -133,7 +143,8 @@ static void print_ip(const struct dhcpv4_option *opt, int elem_size, void (*prin
uint32_t ip;
for (i = 0; i < n; i++) {
- ip = ntohl(*(uint32_t *)(opt->data + i*elem_size));
+ memcpy(&ip, opt->data + i*elem_size, sizeof(ip));
+ ip = ntohl(ip);
if (i)
print(",");
@@ -170,8 +181,10 @@ static void print_route(const struct dhcpv4_option *opt, int elem_size, void (*p
uint32_t ip, gw;
for (i = 0; i < n; i++) {
- ip = ntohl(*(uint32_t *)(opt->data + i*8));
- gw = ntohl(*(uint32_t *)(opt->data + i*8 + 4));
+ memcpy(&ip, opt->data + i*8, sizeof(ip));
+ memcpy(&gw, opt->data + i*8 + 4, sizeof(gw));
+ ip = ntohl(ip);
+ gw = ntohl(gw);
if (i)
print(",");
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index 95ff8568..18e9228d 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -14,13 +14,9 @@
#include <netinet/ip.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
-#include <linux/if.h>
-#ifdef HAVE_GOOD_IFARP
-#include <linux/if_arp.h>
-#endif
-#include <linux/route.h>
-
-#include <pcre.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/route.h>
#include "events.h"
#include "list.h"
@@ -56,7 +52,7 @@
#define SESSION_TERMINATED "Session was terminated"
struct iplink_arg {
- pcre *re;
+ pcre2_code *re;
const char *opt;
long *arg1;
};
@@ -184,9 +180,7 @@ static int conf_check_mac_change;
static int conf_soft_terminate;
static int conf_calling_sid = SID_MAC;
-static unsigned int stat_starting;
-static unsigned int stat_active;
-static unsigned int stat_delayed_offer;
+static struct ipoe_stat_t ipoe_stat;
static mempool_t ses_pool;
static mempool_t disc_item_pool;
@@ -229,6 +223,39 @@ static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struc
static void __terminate(struct ap_session *ses);
static void ipoe_ipv6_disable(struct ipoe_serv *serv);
+void __export ipoe_stat_get(struct ipoe_stat_t *stat)
+{
+ stat->starting = __atomic_load_n(&ipoe_stat.starting, __ATOMIC_RELAXED);
+ stat->active = __atomic_load_n(&ipoe_stat.active, __ATOMIC_RELAXED);
+ stat->delayed_offer = __atomic_load_n(&ipoe_stat.delayed_offer, __ATOMIC_RELAXED);
+}
+
+unsigned int __export ipoe_stat_starting(void)
+{
+ return __atomic_load_n(&ipoe_stat.starting, __ATOMIC_RELAXED);
+}
+
+unsigned int __export ipoe_stat_active(void)
+{
+ return __atomic_load_n(&ipoe_stat.active, __ATOMIC_RELAXED);
+}
+
+static void ipoe_stat_inc(unsigned int *stat)
+{
+ __atomic_add_fetch(stat, 1, __ATOMIC_RELAXED);
+}
+
+static void ipoe_stat_dec(unsigned int *stat)
+{
+ __atomic_sub_fetch(stat, 1, __ATOMIC_RELAXED);
+}
+
+static void ipoe_stat_move(unsigned int *from, unsigned int *to)
+{
+ ipoe_stat_dec(from);
+ ipoe_stat_inc(to);
+}
+
static void ipoe_ctx_switch(struct triton_context_t *ctx, void *arg)
{
if (arg) {
@@ -745,7 +772,7 @@ static void ipoe_session_start(struct ipoe_session *ses)
}
}
- __sync_add_and_fetch(&stat_starting, 1);
+ ipoe_stat_inc(&ipoe_stat.starting);
assert(!ses->ses.username);
@@ -756,6 +783,10 @@ static void ipoe_session_start(struct ipoe_session *ses)
return;
}
+ /* take ownership now so the string is freed by ipoe_session_free()
+ * even if the session terminates before auth_result() consumes it */
+ ses->username = username;
+
ses->ses.unit_idx = ses->serv->ifindex;
triton_event_fire(EV_CTRL_STARTING, &ses->ses);
@@ -766,9 +797,9 @@ static void ipoe_session_start(struct ipoe_session *ses)
if (ses->serv->opt_shared && ipoe_create_interface(ses))
return;
- if (conf_noauth)
+ if (conf_noauth) {
r = PWDB_SUCCESS;
- else {
+ } else {
#ifdef RADIUS
if (radius_loaded) {
ses->radius.send_access_request = ipoe_rad_send_auth_request;
@@ -785,7 +816,6 @@ static void ipoe_session_start(struct ipoe_session *ses)
} else
pass = username;
- ses->username = username;
r = pwdb_check(&ses->ses, (pwdb_callback)auth_result, ses, username, PPP_PAP, pass);
if (r == PWDB_WAIT)
@@ -1023,9 +1053,9 @@ static void __ipoe_session_activate(struct ipoe_session *ses)
in_addr_t gw;
iproute_get(ses->router, &gw, NULL);
if (gw)
- iproute_add(0, ses->siaddr, ses->yiaddr, gw, conf_proto, 32);
+ iproute_add(0, ses->siaddr, ses->yiaddr, gw, conf_proto, 32, NULL);
else
- iproute_add(0, ses->siaddr, ses->router, gw, conf_proto, 32);
+ iproute_add(0, ses->siaddr, ses->router, gw, conf_proto, 32, NULL);
}*/
if (serv->opt_mode == MODE_L3)
@@ -1061,17 +1091,16 @@ static void __ipoe_session_activate(struct ipoe_session *ses)
}
}
- __sync_sub_and_fetch(&stat_starting, 1);
- __sync_add_and_fetch(&stat_active, 1);
+ ipoe_stat_move(&ipoe_stat.starting, &ipoe_stat.active);
ses->started = 1;
ap_session_activate(&ses->ses);
if (ses->ifindex == -1 && !serv->opt_ifcfg) {
if (!serv->opt_ip_unnumbered)
- iproute_add(serv->ifindex, ses->router, ses->yiaddr, 0, conf_proto, ses->mask, 0);
+ iproute_add(serv->ifindex, ses->router, ses->yiaddr, 0, conf_proto, ses->mask, 0, NULL);
else
- iproute_add(serv->ifindex, serv->opt_src ?: ses->router, ses->yiaddr, 0, conf_proto, 32, 0);
+ iproute_add(serv->ifindex, serv->opt_src ?: ses->router, ses->yiaddr, 0, conf_proto, 32, 0, NULL);
}
if (ses->l4_redirect)
@@ -1172,7 +1201,7 @@ static void ipoe_session_started(struct ap_session *s)
if (ses->ses.ipv4->peer_addr != ses->yiaddr)
//ipaddr_add_peer(ses->ses.ifindex, ses->router, ses->yiaddr); // breaks quagga
- iproute_add(ses->ses.ifindex, ses->router, ses->yiaddr, 0, conf_proto, 32, 0);
+ iproute_add(ses->ses.ifindex, ses->router, ses->yiaddr, 0, conf_proto, 32, 0, NULL);
if (ses->ifindex != -1 && ses->xid) {
ses->dhcpv4 = dhcpv4_create(ses->ctrl.ctx, ses->ses.ifname, "");
@@ -1187,9 +1216,9 @@ static void ipoe_session_started(struct ap_session *s)
static void ipoe_session_free(struct ipoe_session *ses)
{
if (ses->started)
- __sync_sub_and_fetch(&stat_active, 1);
+ ipoe_stat_dec(&ipoe_stat.active);
else
- __sync_sub_and_fetch(&stat_starting, 1);
+ ipoe_stat_dec(&ipoe_stat.starting);
if (ses->timer.tpd)
triton_timer_del(&ses->timer);
@@ -1215,6 +1244,9 @@ static void ipoe_session_free(struct ipoe_session *ses)
if (ses->l4_redirect_ipset)
_free(ses->l4_redirect_ipset);
+ if (ses->username)
+ _free(ses->username);
+
triton_context_unregister(&ses->ctx);
if (ses->data)
@@ -1256,9 +1288,9 @@ static void ipoe_session_finished(struct ap_session *s)
} else if (ses->started) {
if (!serv->opt_ifcfg) {
if (!serv->opt_ip_unnumbered)
- iproute_del(serv->ifindex, ses->router, ses->yiaddr, 0, conf_proto, ses->mask, 0);
+ iproute_del(serv->ifindex, ses->router, ses->yiaddr, 0, conf_proto, ses->mask, 0, NULL);
else
- iproute_del(serv->ifindex, serv->opt_src ?: ses->router, ses->yiaddr, 0, conf_proto, 32, 0);
+ iproute_del(serv->ifindex, serv->opt_src ?: ses->router, ses->yiaddr, 0, conf_proto, 32, 0, NULL);
}
}
@@ -1365,10 +1397,10 @@ static struct ipoe_session *ipoe_session_create_dhcpv4(struct ipoe_serv *serv, s
if (ap_shutdown)
return NULL;
- if (conf_max_starting && ap_session_stat.starting >= conf_max_starting)
+ if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting)
return NULL;
- if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions)
+ if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions)
return NULL;
ses = ipoe_session_alloc(serv->ifname);
@@ -1635,7 +1667,7 @@ static void ipoe_serv_disc_timer(struct triton_timer_t *t)
list_del(&d->entry);
mempool_free(d);
- __sync_sub_and_fetch(&stat_delayed_offer, 1);
+ ipoe_stat_dec(&ipoe_stat.delayed_offer);
}
while (!list_empty(&serv->arp_list)) {
@@ -1654,7 +1686,7 @@ static void ipoe_serv_disc_timer(struct triton_timer_t *t)
list_del(&d->entry);
mempool_free(d);
- __sync_sub_and_fetch(&stat_delayed_offer, 1);
+ ipoe_stat_dec(&ipoe_stat.delayed_offer);
}
if (list_empty(&serv->disc_list) && list_empty(&serv->arp_list))
@@ -1675,7 +1707,7 @@ static void ipoe_serv_add_disc_arp(struct ipoe_serv *serv, struct _arphdr *arph,
if (!d)
return;
- __sync_add_and_fetch(&stat_delayed_offer, 1);
+ ipoe_stat_inc(&ipoe_stat.delayed_offer);
memcpy(&d->arph, arph, sizeof(*arph));
clock_gettime(CLOCK_MONOTONIC, &d->ts);
@@ -1695,7 +1727,7 @@ static void ipoe_serv_add_disc(struct ipoe_serv *serv, struct dhcpv4_packet *pac
if (!d)
return;
- __sync_add_and_fetch(&stat_delayed_offer, 1);
+ ipoe_stat_inc(&ipoe_stat.delayed_offer);
dhcpv4_packet_ref(pack);
d->pack = pack;
@@ -1724,7 +1756,7 @@ static int ipoe_serv_check_disc(struct ipoe_serv *serv, struct dhcpv4_packet *pa
dhcpv4_packet_free(d->pack);
mempool_free(d);
- __sync_sub_and_fetch(&stat_delayed_offer, 1);
+ ipoe_stat_dec(&ipoe_stat.delayed_offer);
return 1;
}
@@ -1872,7 +1904,7 @@ static void __ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet
if (!ses)
goto out;
- ses->weight = weight = serv->opt_weight >= 0 ? serv->sess_cnt * serv->opt_weight : (stat_active + 1) * conf_weight;
+ ses->weight = weight = serv->opt_weight >= 0 ? serv->sess_cnt * serv->opt_weight : (ipoe_stat_active() + 1) * conf_weight;
} else {
if (ses->terminate) {
triton_context_call(ses->ctrl.ctx, (triton_event_func)ipoe_session_terminated, ses);
@@ -2003,6 +2035,7 @@ static void ipoe_ses_recv_dhcpv4_relay(struct dhcpv4_packet *pack)
if (!ses->dhcpv4_request) {
ses->dhcpv4_relay_reply = NULL;
+ dhcpv4_packet_free(pack);
return;
}
@@ -2110,10 +2143,10 @@ static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struc
if (ap_shutdown)
return NULL;
- if (conf_max_starting && ap_session_stat.starting >= conf_max_starting)
+ if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting)
return NULL;
- if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions)
+ if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions)
return NULL;
if (connlimit_loaded && connlimit_check(serv->opt_shared ? cl_key_from_ipv4(saddr) : serv->ifindex))
@@ -2330,7 +2363,7 @@ void ipoe_serv_recv_arp(struct ipoe_serv *serv, struct _arphdr *arph)
list_del(&d->entry);
mempool_free(d);
- __sync_sub_and_fetch(&stat_delayed_offer, 1);
+ ipoe_stat_dec(&ipoe_stat.delayed_offer);
break;
}
@@ -2627,14 +2660,14 @@ static void ipoe_serv_release(struct ipoe_serv *serv)
list_del(&d->entry);
dhcpv4_packet_free(d->pack);
mempool_free(d);
- __sync_sub_and_fetch(&stat_delayed_offer, 1);
+ ipoe_stat_dec(&ipoe_stat.delayed_offer);
}
while (!list_empty(&serv->arp_list)) {
struct arp_item *d = list_entry(serv->arp_list.next, typeof(*d), entry);
list_del(&d->entry);
mempool_free(d);
- __sync_sub_and_fetch(&stat_delayed_offer, 1);
+ ipoe_stat_dec(&ipoe_stat.delayed_offer);
}
while (!list_empty(&serv->req_list)) {
@@ -2707,10 +2740,14 @@ static void l4_redirect_ctx_close(struct triton_context_t *ctx)
static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
{
+ struct ipoe_stat_t stat;
+
+ ipoe_stat_get(&stat);
+
cli_send(client, "ipoe:\r\n");
- cli_sendv(client," starting: %u\r\n", stat_starting);
- cli_sendv(client," active: %u\r\n", stat_active);
- cli_sendv(client," delayed: %u\r\n", stat_delayed_offer);
+ cli_sendv(client," starting: %u\r\n", stat.starting);
+ cli_sendv(client," active: %u\r\n", stat.active);
+ cli_sendv(client," delayed: %u\r\n", stat.delayed_offer);
return CLI_CMD_OK;
}
@@ -2728,12 +2765,6 @@ static void print_session_type(struct ap_session *s, char *buf)
*buf = 0;
}
-void __export ipoe_get_stat(unsigned int **starting, unsigned int **active)
-{
- *starting = &stat_starting;
- *active = &stat_active;
-}
-
static void __terminate(struct ap_session *ses)
{
ap_session_terminate(ses, TERM_NAS_REQUEST, 1);
@@ -2771,9 +2802,10 @@ struct ipoe_serv *ipoe_find_serv(const char *ifname)
static int get_offer_delay()
{
struct delay *r, *prev = NULL;
+ unsigned int active = ipoe_stat_active();
list_for_each_entry(r, &conf_offer_delay, entry) {
- if (!prev || stat_active >= r->conn_cnt) {
+ if (!prev || active >= r->conn_cnt) {
prev = r;
continue;
}
@@ -2804,10 +2836,10 @@ void ipoe_vlan_mon_notify(int ifindex, int vid, int vlan_ifindex)
struct ifreq ifr;
char *ptr;
int len, r, svid;
- pcre *re = NULL;
- const char *pcre_err;
+ pcre2_code *re = NULL;
+ int pcre_err;
char *pattern;
- int pcre_offset;
+ PCRE2_SIZE pcre_offset;
char ifname[IFNAMSIZ];
if (!sect)
@@ -2905,15 +2937,17 @@ void ipoe_vlan_mon_notify(int ifindex, int vid, int vlan_ifindex)
memcpy(pattern, opt->val + 3, ptr - (opt->val + 3));
pattern[ptr - (opt->val + 3)] = 0;
- re = pcre_compile2(pattern, 0, NULL, &pcre_err, &pcre_offset, NULL);
+ re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, &pcre_err, &pcre_offset, NULL);
_free(pattern);
if (!re)
continue;
- r = pcre_exec(re, NULL, ifname, len, 0, 0, NULL, 0);
- pcre_free(re);
+ pcre2_match_data *match_data = pcre2_match_data_create(0, NULL);
+ r = pcre2_match(re, (PCRE2_SPTR)ifname, len, 0, 0, match_data, NULL);
+ pcre2_match_data_free(match_data);
+ pcre2_code_free(re);
if (r < 0)
continue;
@@ -3109,12 +3143,12 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (connect(sock, &addr, sizeof(addr))) {
+ if (connect(sock, (struct sockaddr*)&addr, sizeof(addr))) {
log_error("dhcpv4: relay: %s: connect: %s\n", opt_relay, strerror(errno));
goto out_err;
}
- getsockname(sock, &addr, &len);
+ getsockname(sock, (struct sockaddr*)&addr, &len);
opt_giaddr = addr.sin_addr.s_addr;
close(sock);
@@ -3358,8 +3392,12 @@ static void load_interface(const char *opt)
static int __load_interface_re(int index, int flags, const char *name, int iflink, int vid, struct iplink_arg *arg)
{
- if (pcre_exec(arg->re, NULL, name, strlen(name), 0, 0, NULL, 0) < 0)
+ pcre2_match_data *match_data = pcre2_match_data_create(0, NULL);
+ if (pcre2_match(arg->re, (PCRE2_SPTR)name, strlen(name), 0, 0, match_data, NULL) < 0) {
+ pcre2_match_data_free(match_data);
return 0;
+ }
+ pcre2_match_data_free(match_data);
add_interface(name, index, arg->opt, iflink, vid, 0);
@@ -3368,11 +3406,11 @@ static int __load_interface_re(int index, int flags, const char *name, int iflin
static void load_interface_re(const char *opt)
{
- pcre *re = NULL;
- const char *pcre_err;
+ pcre2_code *re = NULL;
+ int pcre_err;
char *pattern;
const char *ptr;
- int pcre_offset;
+ PCRE2_SIZE pcre_offset;
struct iplink_arg arg;
struct ipoe_serv *serv;
@@ -3382,10 +3420,12 @@ static void load_interface_re(const char *opt)
memcpy(pattern, opt + 3, ptr - (opt + 3));
pattern[ptr - (opt + 3)] = 0;
- re = pcre_compile2(pattern, 0, NULL, &pcre_err, &pcre_offset, NULL);
+ re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, &pcre_err, &pcre_offset, NULL);
if (!re) {
- log_error("ipoe: '%s': %s at %i\r\n", pattern, pcre_err, pcre_offset);
+ PCRE2_UCHAR err_msg[64];
+ pcre2_get_error_message(pcre_err, err_msg, sizeof(err_msg));
+ log_error("ipoe: '%s': %s at %i\r\n", pattern, err_msg, (int)pcre_offset);
return;
}
@@ -3398,11 +3438,13 @@ static void load_interface_re(const char *opt)
if (serv->active)
continue;
- if (pcre_exec(re, NULL, serv->ifname, strlen(serv->ifname), 0, 0, NULL, 0) >= 0)
+ pcre2_match_data *match_data = pcre2_match_data_create(0, NULL);
+ if (pcre2_match(re, (PCRE2_SPTR)serv->ifname, strlen(serv->ifname), 0, 0, match_data, NULL) >= 0)
add_interface(serv->ifname, serv->ifindex, opt, 0, 0, 0);
+ pcre2_match_data_free(match_data);
}
- pcre_free(re);
+ pcre2_code_free(re);
_free(pattern);
}
@@ -3474,7 +3516,7 @@ static void load_gw_addr(struct conf_sect_t *sect)
continue;
}
- a->mask1 = ((1 << a->mask) - 1) << (32 - a->mask);
+ a->mask1 = (int)(((1u << a->mask) - 1u) << (32 - a->mask));
list_add_tail(&a->entry, &conf_gw_addr);
}
}
@@ -3538,19 +3580,6 @@ static void load_radius_attrs(void)
}
#endif
-static void strip(char *str)
-{
- char *ptr = str;
- char *endptr = strchr(str, 0);
- while (1) {
- ptr = strchr(ptr, ' ');
- if (ptr)
- memmove(ptr, ptr + 1, endptr - ptr - 1);
- else
- break;
- }
-}
-
int parse_offer_delay(const char *str)
{
char *str1;
@@ -3567,7 +3596,7 @@ int parse_offer_delay(const char *str)
return 0;
str1 = _strdup(str);
- strip(str1);
+ u_strstrip(str1, ' ');
ptr1 = str1;
@@ -3583,17 +3612,23 @@ int parse_offer_delay(const char *str)
memset(r, 0, sizeof(*r));
r->delay = strtol(ptr1, &endptr, 10);
- if (*endptr)
+ if (*endptr) {
+ _free(r);
goto out_err;
+ }
if (list_empty(&conf_offer_delay))
r->conn_cnt = 0;
else {
- if (!ptr3)
+ if (!ptr3) {
+ _free(r);
goto out_err;
+ }
r->conn_cnt = strtol(ptr3 + 1, &endptr, 10);
- if (*endptr)
+ if (*endptr) {
+ _free(r);
goto out_err;
+ }
}
list_add_tail(&r->entry, &conf_offer_delay);
@@ -3608,6 +3643,11 @@ int parse_offer_delay(const char *str)
return 0;
out_err:
+ while (!list_empty(&conf_offer_delay)) {
+ r = list_entry(conf_offer_delay.next, typeof(*r), entry);
+ list_del(&r->entry);
+ _free(r);
+ }
_free(str1);
log_error("ipoe: failed to parse offer-delay\n");
return -1;
@@ -3670,8 +3710,12 @@ static int __load_vlan_mon_re(int index, int flags, const char *name, int iflink
long mask1[4096/8/sizeof(long)];
struct ipoe_serv *serv;
- if (pcre_exec(arg->re, NULL, name, strlen(name), 0, 0, NULL, 0) < 0)
+ pcre2_match_data *match_data = pcre2_match_data_create(0, NULL);
+ if (pcre2_match(arg->re, (PCRE2_SPTR)name, strlen(name), 0, 0, match_data, NULL) < 0) {
+ pcre2_match_data_free(match_data);
return 0;
+ }
+ pcre2_match_data_free(match_data);
if (!(flags & IFF_UP)) {
memset(&ifr, 0, sizeof(ifr));
@@ -3701,11 +3745,11 @@ static int __load_vlan_mon_re(int index, int flags, const char *name, int iflink
static void load_vlan_mon_re(const char *opt, long *mask, int len)
{
- pcre *re = NULL;
- const char *pcre_err;
+ pcre2_code *re = NULL;
+ int pcre_err;
char *pattern;
const char *ptr;
- int pcre_offset;
+ PCRE2_SIZE pcre_offset;
struct iplink_arg arg;
for (ptr = opt; *ptr && *ptr != ','; ptr++);
@@ -3714,10 +3758,12 @@ static void load_vlan_mon_re(const char *opt, long *mask, int len)
memcpy(pattern, opt + 3, ptr - (opt + 3));
pattern[ptr - (opt + 3)] = 0;
- re = pcre_compile2(pattern, 0, NULL, &pcre_err, &pcre_offset, NULL);
+ re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, &pcre_err, &pcre_offset, NULL);
if (!re) {
- log_error("ipoe: '%s': %s at %i\r\n", pattern, pcre_err, pcre_offset);
+ PCRE2_UCHAR err_msg[64];
+ pcre2_get_error_message(pcre_err, err_msg, sizeof(err_msg));
+ log_error("ipoe: '%s': %s at %i\r\n", pattern, err_msg, (int)pcre_offset);
return;
}
@@ -3727,7 +3773,7 @@ static void load_vlan_mon_re(const char *opt, long *mask, int len)
iplink_list((iplink_list_func)__load_vlan_mon_re, &arg);
- pcre_free(re);
+ pcre2_code_free(re);
_free(pattern);
}
diff --git a/accel-pppd/ctrl/ipoe/ipoe.h b/accel-pppd/ctrl/ipoe/ipoe.h
index 116602be..37c26a63 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.h
+++ b/accel-pppd/ctrl/ipoe/ipoe.h
@@ -3,7 +3,7 @@
#include <stdint.h>
#include <pthread.h>
-#include <linux/if.h>
+#include <net/if.h>
#include "triton.h"
#include "ap_session.h"
@@ -130,6 +130,17 @@ struct ipoe_session_info {
uint32_t peer_addr;
};
+struct ipoe_stat_t
+{
+ unsigned int starting;
+ unsigned int active;
+ unsigned int delayed_offer;
+};
+
+void ipoe_stat_get(struct ipoe_stat_t *stat);
+unsigned int ipoe_stat_starting(void);
+unsigned int ipoe_stat_active(void);
+
int ipoe_ipv6_nd_start(struct ipoe_serv *serv);
#ifdef USE_LUA
diff --git a/accel-pppd/ctrl/ipoe/ipoe_netlink.c b/accel-pppd/ctrl/ipoe/ipoe_netlink.c
index e7080e92..7057c91e 100644
--- a/accel-pppd/ctrl/ipoe/ipoe_netlink.c
+++ b/accel-pppd/ctrl/ipoe/ipoe_netlink.c
@@ -10,7 +10,7 @@
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
-#include <linux/if.h>
+#include <net/if.h>
#include <linux/genetlink.h>
#include "triton.h"
diff --git a/accel-pppd/ctrl/l2tp/CMakeLists.txt b/accel-pppd/ctrl/l2tp/CMakeLists.txt
index 66dd3fc6..80cf453b 100644
--- a/accel-pppd/ctrl/l2tp/CMakeLists.txt
+++ b/accel-pppd/ctrl/l2tp/CMakeLists.txt
@@ -8,10 +8,10 @@ ADD_LIBRARY(l2tp SHARED
packet.c
# netlink.c
)
+TARGET_LINK_LIBRARIES(l2tp ${crypto_lib})
#TARGET_LINK_LIBRARIES(l2tp nl nl-genl)
INSTALL(TARGETS l2tp LIBRARY DESTINATION lib${LIB_SUFFIX}/accel-ppp)
FILE(GLOB dict "${CMAKE_CURRENT_SOURCE_DIR}/dict/*")
INSTALL(FILES ${dict} DESTINATION share/accel-ppp/l2tp)
-
diff --git a/accel-pppd/ctrl/l2tp/l2tp.c b/accel-pppd/ctrl/l2tp/l2tp.c
index bb1d1699..cf0c502c 100644
--- a/accel-pppd/ctrl/l2tp/l2tp.c
+++ b/accel-pppd/ctrl/l2tp/l2tp.c
@@ -16,6 +16,8 @@
#include <linux/if_ether.h>
#include <linux/if_pppox.h>
+#include <openssl/md5.h>
+
#include "triton.h"
#include "mempool.h"
#include "log.h"
@@ -24,7 +26,6 @@
#include "utils.h"
#include "iprange.h"
#include "cli.h"
-#include "crypto.h"
#include "connlimit.h"
@@ -99,17 +100,22 @@ static const char *conf_ipv6_pool;
static const char *conf_dpv6_pool;
static const char *conf_ifname;
-static unsigned int stat_conn_starting;
-static unsigned int stat_conn_active;
-static unsigned int stat_conn_finishing;
+struct l2tp_stat_t
+{
+ unsigned int conn_starting;
+ unsigned int conn_active;
+ unsigned int conn_finishing;
-static unsigned int stat_sess_starting;
-static unsigned int stat_sess_active;
-static unsigned int stat_sess_finishing;
+ unsigned int sess_starting;
+ unsigned int sess_active;
+ unsigned int sess_finishing;
-static unsigned int stat_active;
-static unsigned int stat_starting;
-static unsigned int stat_finishing;
+ unsigned int data_starting;
+ unsigned int data_active;
+ unsigned int data_finishing;
+};
+
+static struct l2tp_stat_t l2tp_stat;
struct l2tp_serv_t
{
@@ -123,6 +129,11 @@ struct l2tp_sess_t
struct l2tp_conn_t *paren_conn;
uint16_t sid;
uint16_t peer_sid;
+/* We will keep l2tp attributes Calling-Number/Called-Number and their length while the session exists */
+ char *calling_num;
+ int calling_num_len;
+ char *called_num;
+ int called_num_len;
unsigned int ref_count;
int state1;
@@ -199,6 +210,45 @@ static void l2tp_session_free(struct l2tp_sess_t *sess);
static void l2tp_tunnel_free(struct l2tp_conn_t *conn);
static void apses_stop(void *data);
+static void l2tp_stat_inc(unsigned int *stat)
+{
+ __atomic_add_fetch(stat, 1, __ATOMIC_RELAXED);
+}
+
+static void l2tp_stat_dec(unsigned int *stat)
+{
+ __atomic_sub_fetch(stat, 1, __ATOMIC_RELAXED);
+}
+
+static void l2tp_stat_move(unsigned int *from, unsigned int *to)
+{
+ l2tp_stat_dec(from);
+ l2tp_stat_inc(to);
+}
+
+static void l2tp_stat_get(struct l2tp_stat_t *stat)
+{
+ stat->conn_starting = __atomic_load_n(&l2tp_stat.conn_starting, __ATOMIC_RELAXED);
+ stat->conn_active = __atomic_load_n(&l2tp_stat.conn_active, __ATOMIC_RELAXED);
+ stat->conn_finishing = __atomic_load_n(&l2tp_stat.conn_finishing, __ATOMIC_RELAXED);
+ stat->sess_starting = __atomic_load_n(&l2tp_stat.sess_starting, __ATOMIC_RELAXED);
+ stat->sess_active = __atomic_load_n(&l2tp_stat.sess_active, __ATOMIC_RELAXED);
+ stat->sess_finishing = __atomic_load_n(&l2tp_stat.sess_finishing, __ATOMIC_RELAXED);
+ stat->data_starting = __atomic_load_n(&l2tp_stat.data_starting, __ATOMIC_RELAXED);
+ stat->data_active = __atomic_load_n(&l2tp_stat.data_active, __ATOMIC_RELAXED);
+ stat->data_finishing = __atomic_load_n(&l2tp_stat.data_finishing, __ATOMIC_RELAXED);
+}
+
+unsigned int __export l2tp_stat_starting(void)
+{
+ return __atomic_load_n(&l2tp_stat.data_starting, __ATOMIC_RELAXED);
+}
+
+unsigned int __export l2tp_stat_active(void)
+{
+ return __atomic_load_n(&l2tp_stat.data_active, __ATOMIC_RELAXED);
+}
+
#define log_tunnel(log_func, conn, fmt, ...) \
do { \
@@ -848,16 +898,17 @@ out_err:
return -1;
}
+static void l2tp_session_free_ptr(void *ptr)
+{
+ l2tp_session_free((struct l2tp_sess_t *) ptr);
+}
+
static void l2tp_tunnel_free_sessions(struct l2tp_conn_t *conn)
{
void *sessions = conn->sessions;
conn->sessions = NULL;
-#ifdef HAVE_FREE_FN_T
- tdestroy(sessions, (__free_fn_t)l2tp_session_free);
-#else
- tdestroy(sessions, (void(*)(void *))l2tp_session_free);
-#endif
+ tdestroy(sessions, l2tp_session_free_ptr);
/* Let l2tp_session_free() handle the session counter and
* the reference held by the tunnel.
*/
@@ -870,12 +921,10 @@ static int l2tp_tunnel_disconnect(struct l2tp_conn_t *conn,
case STATE_INIT:
case STATE_WAIT_SCCRP:
case STATE_WAIT_SCCCN:
- __sync_sub_and_fetch(&stat_conn_starting, 1);
- __sync_add_and_fetch(&stat_conn_finishing, 1);
+ l2tp_stat_move(&l2tp_stat.conn_starting, &l2tp_stat.conn_finishing);
break;
case STATE_ESTB:
- __sync_sub_and_fetch(&stat_conn_active, 1);
- __sync_add_and_fetch(&stat_conn_finishing, 1);
+ l2tp_stat_move(&l2tp_stat.conn_active, &l2tp_stat.conn_finishing);
break;
case STATE_FIN:
case STATE_FIN_WAIT:
@@ -955,7 +1004,7 @@ static void __tunnel_destroy(struct l2tp_conn_t *conn)
mempool_free(conn);
- __sync_sub_and_fetch(&stat_conn_finishing, 1);
+ l2tp_stat_dec(&l2tp_stat.conn_finishing);
}
static void tunnel_put(struct l2tp_conn_t *conn)
@@ -983,12 +1032,16 @@ static void __session_destroy(struct l2tp_sess_t *sess)
_free(sess->ctrl.calling_station_id);
if (sess->ctrl.called_station_id)
_free(sess->ctrl.called_station_id);
+ if (sess->calling_num)
+ _free(sess->calling_num);
+ if (sess->called_num)
+ _free(sess->called_num);
log_session(log_info2, sess, "session destroyed\n");
mempool_free(sess);
- __sync_sub_and_fetch(&stat_sess_finishing, 1);
+ l2tp_stat_dec(&l2tp_stat.sess_finishing);
/* Now that the session is fully destroyed,
* drop the reference to the tunnel.
@@ -1021,15 +1074,13 @@ static void l2tp_session_free(struct l2tp_sess_t *sess)
case STATE_WAIT_OCCN:
log_session(log_info2, sess, "deleting session\n");
- __sync_sub_and_fetch(&stat_sess_starting, 1);
- __sync_add_and_fetch(&stat_sess_finishing, 1);
+ l2tp_stat_move(&l2tp_stat.sess_starting, &l2tp_stat.sess_finishing);
break;
case STATE_ESTB:
log_session(log_info2, sess, "deleting session\n");
triton_event_fire(EV_CTRL_FINISHED, &sess->ppp.ses);
- __sync_sub_and_fetch(&stat_sess_active, 1);
- __sync_add_and_fetch(&stat_sess_finishing, 1);
+ l2tp_stat_move(&l2tp_stat.sess_active, &l2tp_stat.sess_finishing);
pthread_mutex_lock(&sess->apses_lock);
if (sess->apses_ctx.tpd)
@@ -1124,12 +1175,10 @@ static void l2tp_tunnel_free(struct l2tp_conn_t *conn)
case STATE_INIT:
case STATE_WAIT_SCCRP:
case STATE_WAIT_SCCCN:
- __sync_sub_and_fetch(&stat_conn_starting, 1);
- __sync_add_and_fetch(&stat_conn_finishing, 1);
+ l2tp_stat_move(&l2tp_stat.conn_starting, &l2tp_stat.conn_finishing);
break;
case STATE_ESTB:
- __sync_sub_and_fetch(&stat_conn_active, 1);
- __sync_add_and_fetch(&stat_conn_finishing, 1);
+ l2tp_stat_move(&l2tp_stat.conn_active, &l2tp_stat.conn_finishing);
break;
case STATE_FIN:
case STATE_FIN_WAIT:
@@ -1252,7 +1301,7 @@ static void __apses_destroy(void *data)
log_ppp_info2("session destroyed\n");
- __sync_sub_and_fetch(&stat_finishing, 1);
+ l2tp_stat_dec(&l2tp_stat.data_finishing);
/* Drop reference to the L2TP session */
session_put(sess);
@@ -1267,12 +1316,10 @@ static void apses_finished(struct ap_session *apses)
switch (sess->apses_state) {
case APSTATE_STARTING:
- __sync_sub_and_fetch(&stat_starting, 1);
- __sync_add_and_fetch(&stat_finishing, 1);
+ l2tp_stat_move(&l2tp_stat.data_starting, &l2tp_stat.data_finishing);
break;
case APSTATE_STARTED:
- __sync_sub_and_fetch(&stat_active, 1);
- __sync_add_and_fetch(&stat_finishing, 1);
+ l2tp_stat_move(&l2tp_stat.data_active, &l2tp_stat.data_finishing);
break;
case APSTATE_FINISHING:
break;
@@ -1313,12 +1360,10 @@ static void apses_stop(void *data)
switch (sess->apses_state) {
case APSTATE_INIT:
case APSTATE_STARTING:
- __sync_sub_and_fetch(&stat_starting, 1);
- __sync_add_and_fetch(&stat_finishing, 1);
+ l2tp_stat_move(&l2tp_stat.data_starting, &l2tp_stat.data_finishing);
break;
case APSTATE_STARTED:
- __sync_sub_and_fetch(&stat_active, 1);
- __sync_add_and_fetch(&stat_finishing, 1);
+ l2tp_stat_move(&l2tp_stat.data_active, &l2tp_stat.data_finishing);
break;
case APSTATE_FINISHING:
break;
@@ -1377,8 +1422,7 @@ static void apses_started(struct ap_session *apses)
return;
}
- __sync_sub_and_fetch(&stat_starting, 1);
- __sync_add_and_fetch(&stat_active, 1);
+ l2tp_stat_move(&l2tp_stat.data_starting, &l2tp_stat.data_active);
sess->apses_state = APSTATE_STARTED;
log_ppp_info1("session started over l2tp session %hu-%hu, %hu-%hu\n",
@@ -1507,7 +1551,7 @@ static struct l2tp_sess_t *l2tp_tunnel_alloc_session(struct l2tp_conn_t *conn)
tunnel_hold(conn);
session_hold(sess);
- __sync_add_and_fetch(&stat_sess_starting, 1);
+ l2tp_stat_inc(&l2tp_stat.sess_starting);
return sess;
}
@@ -1613,7 +1657,7 @@ static struct l2tp_conn_t *l2tp_tunnel_alloc(const struct sockaddr_in *peer,
strerror(errno));
goto err_conn_fd;
}
- if (bind(conn->hnd.fd, host, sizeof(*host))) {
+ if (bind(conn->hnd.fd, (struct sockaddr*)host, sizeof(*host))) {
log_error("l2tp: impossible to allocate new tunnel:"
" bind() failed: %s\n", strerror(errno));
goto err_conn_fd;
@@ -1646,7 +1690,7 @@ static struct l2tp_conn_t *l2tp_tunnel_alloc(const struct sockaddr_in *peer,
goto err_conn_fd;
}
- if (getsockname(conn->hnd.fd, &conn->host_addr, &hostaddrlen) < 0) {
+ if (getsockname(conn->hnd.fd, (struct sockaddr*)&conn->host_addr, &hostaddrlen) < 0) {
log_error("l2tp: impossible to allocate new tunnel:"
" getsockname() failed: %s\n", strerror(errno));
goto err_conn_fd;
@@ -1726,7 +1770,7 @@ static struct l2tp_conn_t *l2tp_tunnel_alloc(const struct sockaddr_in *peer,
conn->peer_rcv_wnd_sz = DEFAULT_PEER_RECV_WINDOW_SIZE;
tunnel_hold(conn);
- __sync_add_and_fetch(&stat_conn_starting, 1);
+ l2tp_stat_inc(&l2tp_stat.conn_starting);
return conn;
@@ -1747,7 +1791,7 @@ static inline int l2tp_tunnel_update_peerport(struct l2tp_conn_t *conn,
int res;
conn->peer_addr.sin_port = port_nbo;
- res = connect(conn->hnd.fd, &conn->peer_addr, sizeof(conn->peer_addr));
+ res = connect(conn->hnd.fd, (struct sockaddr*)&conn->peer_addr, sizeof(conn->peer_addr));
if (res < 0) {
log_tunnel(log_error, conn,
"impossible to update peer port from %hu to %hu:"
@@ -1775,25 +1819,52 @@ static int l2tp_session_start_data_channel(struct l2tp_sess_t *sess)
sess->ctrl.max_mtu = conf_ppp_max_mtu;
sess->ctrl.mppe = conf_mppe;
- sess->ctrl.calling_station_id = _malloc(17);
- if (sess->ctrl.calling_station_id == NULL) {
- log_session(log_error, sess,
- "impossible to start data channel:"
- " allocation of calling station ID failed\n");
- goto err;
+ /* If l2tp calling number avp exists, we use it, otherwise we use lac ip */
+ if (sess->calling_num != NULL) {
+ sess->ctrl.calling_station_id = _malloc(sess->calling_num_len+1);
+ if (sess->ctrl.calling_station_id == NULL) {
+ log_session(log_error, sess,
+ "impossible to start data channel:"
+ " allocation of calling station ID failed\n");
+ goto err;
+ }else {
+ strcpy(sess->ctrl.calling_station_id, sess->calling_num);
+ }
+ } else {
+ sess->ctrl.calling_station_id = _malloc(17);
+ if (sess->ctrl.calling_station_id == NULL) {
+ log_session(log_error, sess,
+ "impossible to start data channel:"
+ " allocation of calling station ID failed\n");
+ goto err;
+ } else {
+ u_inet_ntoa(sess->paren_conn->peer_addr.sin_addr.s_addr,
+ sess->ctrl.calling_station_id);
+ }
}
- u_inet_ntoa(sess->paren_conn->peer_addr.sin_addr.s_addr,
- sess->ctrl.calling_station_id);
-
- sess->ctrl.called_station_id = _malloc(17);
- if (sess->ctrl.called_station_id == NULL) {
- log_session(log_error, sess,
- "impossible to start data channel:"
- " allocation of called station ID failed\n");
- goto err;
+ /* If l2tp called number avp exists, we use it, otherwise we use my ip */
+ if (sess->called_num != NULL) {
+ sess->ctrl.called_station_id = _malloc(sess->called_num_len+1);
+ if (sess->ctrl.called_station_id == NULL) {
+ log_session(log_error, sess,
+ "impossible to start data channel:"
+ " allocation of called station ID failed\n");
+ goto err;
+ } else {
+ strcpy(sess->ctrl.called_station_id, sess->called_num);
+ }
+ } else {
+ sess->ctrl.called_station_id = _malloc(17);
+ if (sess->ctrl.called_station_id == NULL) {
+ log_session(log_error, sess,
+ "impossible to start data channel:"
+ " allocation of called station ID failed\n");
+ goto err;
+ } else {
+ u_inet_ntoa(sess->paren_conn->host_addr.sin_addr.s_addr,
+ sess->ctrl.called_station_id);
+ }
}
- u_inet_ntoa(sess->paren_conn->host_addr.sin_addr.s_addr,
- sess->ctrl.called_station_id);
if (conf_ip_pool) {
sess->ppp.ses.ipv4_pool_name = _strdup(conf_ip_pool);
@@ -1844,7 +1915,7 @@ static int l2tp_session_start_data_channel(struct l2tp_sess_t *sess)
goto err_put_ctx;
}
- __sync_add_and_fetch(&stat_starting, 1);
+ l2tp_stat_inc(&l2tp_stat.data_starting);
return 0;
@@ -1974,8 +2045,7 @@ static int l2tp_session_connect(struct l2tp_sess_t *sess)
}
triton_event_fire(EV_CTRL_STARTED, &sess->ppp.ses);
- __sync_sub_and_fetch(&stat_sess_starting, 1);
- __sync_add_and_fetch(&stat_sess_active, 1);
+ l2tp_stat_move(&l2tp_stat.sess_starting, &l2tp_stat.sess_active);
sess->state1 = STATE_ESTB;
if (l2tp_session_start_data_channel(sess) < 0) {
@@ -2053,8 +2123,7 @@ static int l2tp_tunnel_connect(struct l2tp_conn_t *conn)
close(tunnel_fd);
- __sync_sub_and_fetch(&stat_conn_starting, 1);
- __sync_add_and_fetch(&stat_conn_active, 1);
+ l2tp_stat_move(&l2tp_stat.conn_starting, &l2tp_stat.conn_active);
conn->state = STATE_ESTB;
return 0;
@@ -2684,12 +2753,10 @@ static void l2tp_tunnel_finwait(struct l2tp_conn_t *conn)
switch (conn->state) {
case STATE_WAIT_SCCRP:
case STATE_WAIT_SCCCN:
- __sync_sub_and_fetch(&stat_conn_starting, 1);
- __sync_add_and_fetch(&stat_conn_finishing, 1);
+ l2tp_stat_move(&l2tp_stat.conn_starting, &l2tp_stat.conn_finishing);
break;
case STATE_ESTB:
- __sync_sub_and_fetch(&stat_conn_active, 1);
- __sync_add_and_fetch(&stat_conn_finishing, 1);
+ l2tp_stat_move(&l2tp_stat.conn_active, &l2tp_stat.conn_finishing);
break;
case STATE_FIN:
break;
@@ -2769,10 +2836,10 @@ static int l2tp_recv_SCCRQ(const struct l2tp_serv_t *serv,
return 0;
}
- if (conf_max_starting && ap_session_stat.starting >= conf_max_starting)
+ if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting)
return 0;
- if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions)
+ if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions)
return 0;
if (triton_module_loaded("connlimit")
@@ -3299,6 +3366,10 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn,
uint16_t sid = 0;
uint16_t res = 0;
uint16_t err = 0;
+ uint8_t calling[L2TP_AVP_LEN_MASK] = {0};
+ uint8_t called[L2TP_AVP_LEN_MASK] = {0};
+ int n = 0;
+ int m = 0;
if (conn->state != STATE_ESTB && conn->lns_mode) {
log_tunnel(log_warn, conn, "discarding unexpected ICRQ\n");
@@ -3311,10 +3382,10 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn,
return 0;
}
- if (conf_max_starting && ap_session_stat.starting >= conf_max_starting)
+ if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting)
return 0;
- if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions)
+ if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions)
return 0;
if (triton_module_loaded("connlimit")
@@ -3336,7 +3407,17 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn,
case Call_Serial_Number:
case Bearer_Type:
case Calling_Number:
+ /* Save Calling-Number L2TP attribute locally */
+ if (attr->attr->id == Calling_Number) {
+ n = attr->length;
+ memcpy(calling,attr->val.octets,n);
+ }
case Called_Number:
+ /* Save Called-Number L2TP attribute locally */
+ if (attr->attr->id == Called_Number) {
+ m = attr->length;
+ memcpy(called,attr->val.octets,m);
+ }
case Sub_Address:
case Physical_Channel_ID:
break;
@@ -3375,6 +3456,30 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn,
sess->peer_sid = peer_sid;
sid = sess->sid;
+ /* Allocate memory for Calling-Number if exists, and put it to l2tp_sess_t structure */
+ if (n > 0) {
+ sess->calling_num = _malloc(n+1);
+ if (sess->calling_num == NULL) {
+ log_tunnel(log_warn, conn, "can't allocate memory for Calling Number attribute. Will use LAC IP instead\n");
+ }else{
+ memcpy(sess->calling_num, calling, n);
+ sess->calling_num[n] = '\0';
+ sess->calling_num_len = n;
+ }
+ }
+
+ /* Allocate memory for Called-Number if exists, and put it to l2tp_sess_t structure */
+ if (m > 1) {
+ sess->called_num = _malloc(m+1);
+ if (sess->called_num == NULL) {
+ log_tunnel(log_warn, conn, "can't allocate memory for Called Number attribute. Will use my IP instead\n");
+ } else {
+ memcpy(sess->called_num, called, m);
+ sess->called_num[m] = '\0';
+ sess->called_num_len = m;
+ }
+ }
+
if (unknown_attr) {
log_tunnel(log_error, conn, "impossible to handle ICRQ:"
" unknown mandatory attribute type %i,"
@@ -3394,8 +3499,8 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn,
goto out_reject;
}
- log_tunnel(log_info1, conn, "new session %hu-%hu created following"
- " reception of ICRQ\n", sid, peer_sid);
+ log_tunnel(log_info1, conn, "new session %hu-%hu with calling num %s len %d, called num %s len %d created following"
+ " reception of ICRQ\n", sid, peer_sid, sess->calling_num, sess->calling_num_len, sess->called_num, sess->called_num_len);
return 0;
@@ -3617,10 +3722,10 @@ static int l2tp_recv_OCRQ(struct l2tp_conn_t *conn,
return 0;
}
- if (conf_max_starting && ap_session_stat.starting >= conf_max_starting)
+ if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting)
return 0;
- if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions)
+ if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions)
return 0;
if (triton_module_loaded("connlimit")
@@ -4637,21 +4742,25 @@ err_fd:
static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
{
+ struct l2tp_stat_t stat;
+
+ l2tp_stat_get(&stat);
+
cli_send(client, "l2tp:\r\n");
cli_send(client, " tunnels:\r\n");
- cli_sendv(client, " starting: %u\r\n", stat_conn_starting);
- cli_sendv(client, " active: %u\r\n", stat_conn_active);
- cli_sendv(client, " finishing: %u\r\n", stat_conn_finishing);
+ cli_sendv(client, " starting: %u\r\n", stat.conn_starting);
+ cli_sendv(client, " active: %u\r\n", stat.conn_active);
+ cli_sendv(client, " finishing: %u\r\n", stat.conn_finishing);
cli_send(client, " sessions (control channels):\r\n");
- cli_sendv(client, " starting: %u\r\n", stat_sess_starting);
- cli_sendv(client, " active: %u\r\n", stat_sess_active);
- cli_sendv(client, " finishing: %u\r\n", stat_sess_finishing);
+ cli_sendv(client, " starting: %u\r\n", stat.sess_starting);
+ cli_sendv(client, " active: %u\r\n", stat.sess_active);
+ cli_sendv(client, " finishing: %u\r\n", stat.sess_finishing);
cli_send(client, " sessions (data channels):\r\n");
- cli_sendv(client, " starting: %u\r\n", stat_starting);
- cli_sendv(client, " active: %u\r\n", stat_active);
- cli_sendv(client, " finishing: %u\r\n", stat_finishing);
+ cli_sendv(client, " starting: %u\r\n", stat.data_starting);
+ cli_sendv(client, " active: %u\r\n", stat.data_active);
+ cli_sendv(client, " finishing: %u\r\n", stat.data_finishing);
return CLI_CMD_OK;
}
@@ -4857,12 +4966,6 @@ static void l2tp_create_session_help(char * const *fields, int fields_cnt,
" - place new call in tunnel <tid>\r\n");
}
-void __export l2tp_get_stat(unsigned int **starting, unsigned int **active)
-{
- *starting = &stat_starting;
- *active = &stat_active;
-}
-
static void load_config(void)
{
const char *opt;
diff --git a/accel-pppd/ctrl/l2tp/l2tp.h b/accel-pppd/ctrl/l2tp/l2tp.h
index 76de867f..2f113a25 100644
--- a/accel-pppd/ctrl/l2tp/l2tp.h
+++ b/accel-pppd/ctrl/l2tp/l2tp.h
@@ -77,6 +77,9 @@ struct l2tp_packet_t
extern int conf_verbose;
extern int conf_avp_permissive;
+unsigned int l2tp_stat_starting(void);
+unsigned int l2tp_stat_active(void);
+
static inline int l2tp_packet_is_ZLB(const struct l2tp_packet_t *pack)
{
return list_empty(&pack->attrs);
diff --git a/accel-pppd/ctrl/l2tp/packet.c b/accel-pppd/ctrl/l2tp/packet.c
index 97e205f3..1e1488b5 100644
--- a/accel-pppd/ctrl/l2tp/packet.c
+++ b/accel-pppd/ctrl/l2tp/packet.c
@@ -8,7 +8,8 @@
#include <fcntl.h>
#include <arpa/inet.h>
-#include "crypto.h"
+#include <openssl/md5.h>
+
#include "triton.h"
#include "log.h"
#include "mempool.h"
@@ -280,7 +281,7 @@ int l2tp_recv(int fd, struct l2tp_packet_t **p, struct in_pktinfo *pkt_info,
ptr = (uint8_t *)(hdr + 1);
addr_len = sizeof(addr);
- n = recvfrom(fd, buf, L2TP_MAX_PACKET_SIZE, 0, &addr, &addr_len);
+ n = recvfrom(fd, buf, L2TP_MAX_PACKET_SIZE, 0, (struct sockaddr*)&addr, &addr_len);
if (n < 0) {
mempool_free(buf);
if (errno == EAGAIN) {
@@ -552,7 +553,7 @@ int l2tp_packet_send(int sock, struct l2tp_packet_t *pack)
memcpy(buf, &pack->hdr, sizeof(pack->hdr));
hdr->flags = htons(pack->hdr.flags);
- n = sendto(sock, buf, len, 0, &pack->addr, sizeof(pack->addr));
+ n = sendto(sock, buf, len, 0, (struct sockaddr*)&pack->addr, sizeof(pack->addr));
mempool_free(buf);
if (n < 0) {
diff --git a/accel-pppd/ctrl/pppoe/CMakeLists.txt b/accel-pppd/ctrl/pppoe/CMakeLists.txt
index fd4f9a36..92733b74 100644
--- a/accel-pppd/ctrl/pppoe/CMakeLists.txt
+++ b/accel-pppd/ctrl/pppoe/CMakeLists.txt
@@ -13,7 +13,12 @@ SET(sources ${sources} tr101.c)
ENDIF(RADIUS)
ADD_LIBRARY(pppoe SHARED ${sources})
-TARGET_LINK_LIBRARIES(pppoe vlan-mon connlimit)
+# if MUSL is set then we need to link with the connlimit library
+IF (MUSL)
+ TARGET_LINK_LIBRARIES(pppoe vlan-mon connlimit ${crypto_lib})
+ELSE (MUSL)
+ TARGET_LINK_LIBRARIES(pppoe vlan-mon ${crypto_lib})
+ENDIF (MUSL)
set_property(TARGET pppoe PROPERTY CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set_property(TARGET pppoe PROPERTY INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/accel-ppp)
diff --git a/accel-pppd/ctrl/pppoe/cli.c b/accel-pppd/ctrl/pppoe/cli.c
index d8399543..453c0cf3 100644
--- a/accel-pppd/ctrl/pppoe/cli.c
+++ b/accel-pppd/ctrl/pppoe/cli.c
@@ -88,16 +88,20 @@ help:
static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
{
+ struct pppoe_stat_t stat;
+
+ pppoe_stat_get(&stat);
+
cli_send(client, "pppoe:\r\n");
- cli_sendv(client, " starting: %u\r\n", stat_starting);
- cli_sendv(client, " active: %u\r\n", stat_active);
- cli_sendv(client, " delayed PADO: %u\r\n", stat_delayed_pado);
- cli_sendv(client, " recv PADI: %lu\r\n", stat_PADI_recv);
- cli_sendv(client, " drop PADI: %lu\r\n", stat_PADI_drop);
- cli_sendv(client, " sent PADO: %lu\r\n", stat_PADO_sent);
- cli_sendv(client, " recv PADR(dup): %lu(%lu)\r\n", stat_PADR_recv, stat_PADR_dup_recv);
- cli_sendv(client, " sent PADS: %lu\r\n", stat_PADS_sent);
- cli_sendv(client, " filtered: %lu\r\n", stat_filtered);
+ cli_sendv(client, " starting: %u\r\n", stat.starting);
+ cli_sendv(client, " active: %u\r\n", stat.active);
+ cli_sendv(client, " delayed PADO: %u\r\n", stat.delayed_PADO);
+ cli_sendv(client, " recv PADI: %lu\r\n", stat.PADI_recv);
+ cli_sendv(client, " drop PADI: %lu\r\n", stat.PADI_drop);
+ cli_sendv(client, " sent PADO: %lu\r\n", stat.PADO_sent);
+ cli_sendv(client, " recv PADR(dup): %lu(%lu)\r\n", stat.PADR_recv, stat.PADR_dup_recv);
+ cli_sendv(client, " sent PADS: %lu\r\n", stat.PADS_sent);
+ cli_sendv(client, " filtered: %lu\r\n", stat.filtered);
return CLI_CMD_OK;
}
diff --git a/accel-pppd/ctrl/pppoe/disc.c b/accel-pppd/ctrl/pppoe/disc.c
index 8a82e1d2..f7f5c781 100644
--- a/accel-pppd/ctrl/pppoe/disc.c
+++ b/accel-pppd/ctrl/pppoe/disc.c
@@ -77,7 +77,7 @@ static struct disc_net *init_net(const struct ap_net *net)
fcntl(sock, F_SETFD, FD_CLOEXEC);
net->set_nonblocking(sock, 1);
- n = _malloc(sizeof(*net) + (HASH_BITS + 1) * sizeof(struct tree));
+ n = _malloc(sizeof(*n) + (HASH_BITS + 1) * sizeof(struct tree));
tree = n->tree;
for (i = 0; i <= HASH_BITS; i++) {
@@ -110,7 +110,7 @@ static void free_net(struct disc_net *net)
pthread_mutex_lock(&nets_lock);
for (i = 0; i < MAX_NET; i++) {
if (nets[i] == net) {
- memcpy(nets + i, nets + i + 1, net_cnt - i - 1);
+ memmove(nets + i, nets + i + 1, (net_cnt - i - 1) * sizeof(nets[0]));
net_cnt--;
break;
}
@@ -329,7 +329,7 @@ static int disc_read(struct triton_md_handler_t *h)
}
if (mac_filter_check(ethhdr->h_source)) {
- __sync_add_and_fetch(&stat_filtered, 1);
+ pppoe_stat_add_filtered();
continue;
}
@@ -363,6 +363,7 @@ static int disc_read(struct triton_md_handler_t *h)
if (hdr->type != 1) {
if (conf_verbose)
log_warn("pppoe: discarding packet (unsupported type %i)\n", hdr->type);
+ continue;
}
if (forward(net, src.sll_ifindex, pack, n))
diff --git a/accel-pppd/ctrl/pppoe/dpado.c b/accel-pppd/ctrl/pppoe/dpado.c
index 71faa130..dc570dda 100644
--- a/accel-pppd/ctrl/pppoe/dpado.c
+++ b/accel-pppd/ctrl/pppoe/dpado.c
@@ -11,6 +11,7 @@
#include "triton.h"
#include "log.h"
#include "memdebug.h"
+#include "utils.h"
#include "pppoe.h"
@@ -60,27 +61,15 @@ void dpado_check_prev(int conn_cnt)
pthread_mutex_unlock(&dpado_range_lock);
}
-static void strip(char *str)
-{
- char *ptr = str;
- char *endptr = strchr(str, 0);
- while (1) {
- ptr = strchr(ptr, ' ');
- if (ptr)
- memmove(ptr, ptr + 1, endptr - ptr - 1);
- else
- break;
- }
-}
-
int dpado_parse(const char *str)
{
char *str1 = _strdup(str);
char *ptr1, *ptr2, *ptr3, *endptr;
+ unsigned int active = pppoe_stat_active();
LIST_HEAD(range_list);
struct dpado_range_t *r;
- strip(str1);
+ u_strstrip(str1, ' ');
ptr1 = str1;
@@ -96,17 +85,23 @@ int dpado_parse(const char *str)
memset(r, 0, sizeof(*r));
r->pado_delay = strtol(ptr1, &endptr, 10);
- if (*endptr)
+ if (*endptr) {
+ _free(r);
goto out_err;
+ }
if (list_empty(&range_list))
r->conn_cnt = INT_MAX;
else {
- if (!ptr3)
+ if (!ptr3) {
+ _free(r);
goto out_err;
+ }
r->conn_cnt = strtol(ptr3 + 1, &endptr, 10);
- if (*endptr)
+ if (*endptr) {
+ _free(r);
goto out_err;
+ }
}
list_add_tail(&r->entry, &range_list);
@@ -131,7 +126,7 @@ int dpado_parse(const char *str)
dpado_range_prev = NULL;
list_for_each_entry(r, &dpado_range_list, entry) {
- if (!dpado_range_prev || stat_active >= r->conn_cnt) {
+ if (!dpado_range_prev || active >= r->conn_cnt) {
dpado_range_prev = r;
if (r->entry.next != &dpado_range_list)
dpado_range_next = list_entry(r->entry.next, typeof(*r), entry);
@@ -159,6 +154,11 @@ int dpado_parse(const char *str)
return 0;
out_err:
+ while (!list_empty(&range_list)) {
+ r = list_entry(range_list.next, typeof(*r), entry);
+ list_del(&r->entry);
+ _free(r);
+ }
_free(str1);
log_emerg("pppoe: pado_delay: invalid format\n");
return -1;
diff --git a/accel-pppd/ctrl/pppoe/mac_filter.c b/accel-pppd/ctrl/pppoe/mac_filter.c
index ba78df6b..3a6a00d6 100644
--- a/accel-pppd/ctrl/pppoe/mac_filter.c
+++ b/accel-pppd/ctrl/pppoe/mac_filter.c
@@ -92,15 +92,17 @@ static int mac_filter_load(const char *opt)
log_warn("pppoe: mac-filter:%s:%i: address is invalid\n", name, line);
continue;
}
- mac = _malloc(sizeof(*mac));
for (i = 0; i < ETH_ALEN; i++) {
- if (n[i] > 255) {
- log_warn("pppoe: mac-filter:%s:%i: address is invalid\n", name, line);
- _free(mac);
- continue;
- }
- mac->addr[i] = n[i];
+ if (n[i] > 255)
+ break;
}
+ if (i < ETH_ALEN) {
+ log_warn("pppoe: mac-filter:%s:%i: address is invalid\n", name, line);
+ continue;
+ }
+ mac = _malloc(sizeof(*mac));
+ for (i = 0; i < ETH_ALEN; i++)
+ mac->addr[i] = n[i];
list_add_tail(&mac->entry, &mac_list);
}
pthread_rwlock_unlock(&lock);
diff --git a/accel-pppd/ctrl/pppoe/pppoe.c b/accel-pppd/ctrl/pppoe/pppoe.c
index dd623acc..0cc23180 100644
--- a/accel-pppd/ctrl/pppoe/pppoe.c
+++ b/accel-pppd/ctrl/pppoe/pppoe.c
@@ -11,11 +11,6 @@
#include <net/ethernet.h>
#include <netpacket/packet.h>
#include <arpa/inet.h>
-#ifdef HAVE_PRINTF_H
-#include <printf.h>
-#endif
-
-#include "crypto.h"
#include "events.h"
#include "triton.h"
@@ -48,6 +43,7 @@ struct pppoe_conn_t {
struct pppoe_serv_t *serv;
uint16_t sid;
uint8_t addr[ETH_ALEN];
+ unsigned int ppp_starting:1;
unsigned int ppp_started:1;
struct pppoe_tag *relay_sid;
@@ -83,7 +79,7 @@ struct padi_t
};
struct iplink_arg {
- pcre *re;
+ pcre2_code *re;
const char *opt;
void *cli;
long *arg1;
@@ -114,17 +110,8 @@ static mempool_t conn_pool;
static mempool_t pado_pool;
static mempool_t padi_pool;
-unsigned int stat_starting;
-unsigned int stat_active;
-unsigned int stat_delayed_pado;
-unsigned long stat_PADI_recv;
-unsigned long stat_PADI_drop;
-unsigned long stat_PADO_sent;
-unsigned long stat_PADR_recv;
-unsigned long stat_PADR_dup_recv;
-unsigned long stat_PADS_sent;
+static struct pppoe_stat_t pppoe_stat;
unsigned int total_padi_cnt;
-unsigned long stat_filtered;
pthread_rwlock_t serv_lock = PTHREAD_RWLOCK_INITIALIZER;
LIST_HEAD(serv_list);
@@ -136,6 +123,35 @@ static unsigned long *sid_map;
static unsigned long *sid_ptr;
static int sid_idx;
+void __export pppoe_stat_get(struct pppoe_stat_t *stat)
+{
+ stat->starting = __atomic_load_n(&pppoe_stat.starting, __ATOMIC_RELAXED);
+ stat->active = __atomic_load_n(&pppoe_stat.active, __ATOMIC_RELAXED);
+ stat->delayed_PADO = __atomic_load_n(&pppoe_stat.delayed_PADO, __ATOMIC_RELAXED);
+ stat->PADI_recv = __atomic_load_n(&pppoe_stat.PADI_recv, __ATOMIC_RELAXED);
+ stat->PADI_drop = __atomic_load_n(&pppoe_stat.PADI_drop, __ATOMIC_RELAXED);
+ stat->PADO_sent = __atomic_load_n(&pppoe_stat.PADO_sent, __ATOMIC_RELAXED);
+ stat->PADR_recv = __atomic_load_n(&pppoe_stat.PADR_recv, __ATOMIC_RELAXED);
+ stat->PADR_dup_recv = __atomic_load_n(&pppoe_stat.PADR_dup_recv, __ATOMIC_RELAXED);
+ stat->PADS_sent = __atomic_load_n(&pppoe_stat.PADS_sent, __ATOMIC_RELAXED);
+ stat->filtered = __atomic_load_n(&pppoe_stat.filtered, __ATOMIC_RELAXED);
+}
+
+unsigned int __export pppoe_stat_starting(void)
+{
+ return __atomic_load_n(&pppoe_stat.starting, __ATOMIC_RELAXED);
+}
+
+unsigned int __export pppoe_stat_active(void)
+{
+ return __atomic_load_n(&pppoe_stat.active, __ATOMIC_RELAXED);
+}
+
+void __export pppoe_stat_add_filtered(void)
+{
+ __atomic_add_fetch(&pppoe_stat.filtered, 1, __ATOMIC_RELAXED);
+}
+
static uint8_t bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static void pppoe_send_PADT(struct pppoe_conn_t *conn);
@@ -173,9 +189,12 @@ static void disconnect(struct pppoe_conn_t *conn)
struct pppoe_serv_t *serv = conn->serv;
if (conn->ppp_started) {
- dpado_check_prev(__sync_fetch_and_sub(&stat_active, 1));
+ dpado_check_prev(__atomic_fetch_sub(&pppoe_stat.active, 1, __ATOMIC_RELAXED));
conn->ppp_started = 0;
ap_session_terminate(&conn->ppp.ses, TERM_USER_REQUEST, 1);
+ } else if (conn->ppp_starting) {
+ __atomic_sub_fetch(&pppoe_stat.starting, 1, __ATOMIC_RELAXED);
+ conn->ppp_starting = 0;
}
pppoe_send_PADT(conn);
@@ -232,7 +251,7 @@ static void ppp_finished(struct ap_session *ses)
log_ppp_debug("pppoe: ppp finished\n");
if (conn->ppp_started) {
- dpado_check_prev(__sync_fetch_and_sub(&stat_active, 1));
+ dpado_check_prev(__atomic_fetch_sub(&pppoe_stat.active, 1, __ATOMIC_RELAXED));
conn->ppp_started = 0;
triton_context_call(&conn->ctx, (triton_event_func)disconnect, conn);
}
@@ -279,9 +298,15 @@ static void pppoe_conn_ctx_switch(struct triton_context_t *ctx, void *arg)
static struct pppoe_conn_t *allocate_channel(struct pppoe_serv_t *serv, const uint8_t *addr, const struct pppoe_tag *host_uniq, const struct pppoe_tag *relay_sid, const struct pppoe_tag *service_name, const struct pppoe_tag *tr101, const uint8_t *cookie, uint16_t ppp_max_payload)
{
+ struct pppoe_tag empty_service_name = {
+ .tag_type = htons(TAG_SERVICE_NAME),
+ };
struct pppoe_conn_t *conn;
unsigned long *old_sid_ptr;
+ if (!service_name)
+ service_name = &empty_service_name;
+
conn = mempool_alloc(conn_pool);
if (!conn) {
log_error("pppoe: out of memory\n");
@@ -450,6 +475,9 @@ static void connect_channel(struct pppoe_conn_t *conn)
struct sockaddr_pppox sp;
triton_event_fire(EV_CTRL_STARTING, &conn->ppp.ses);
+ conn->ppp_starting = 1;
+ __atomic_add_fetch(&pppoe_stat.starting, 1, __ATOMIC_RELAXED);
+
triton_event_fire(EV_CTRL_STARTED, &conn->ppp.ses);
sock = net->socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OE);
@@ -486,9 +514,11 @@ static void connect_channel(struct pppoe_conn_t *conn)
}
#endif
+ conn->ppp_starting = 0;
conn->ppp_started = 1;
- dpado_check_next(__sync_add_and_fetch(&stat_active, 1));
+ __atomic_sub_fetch(&pppoe_stat.starting, 1, __ATOMIC_RELAXED);
+ dpado_check_next(__atomic_add_fetch(&pppoe_stat.active, 1, __ATOMIC_RELAXED));
return;
@@ -822,7 +852,7 @@ static void pppoe_send_PADO(struct pppoe_serv_t *serv, const uint8_t *addr, cons
if (conf_verbose)
print_packet(serv->ifname, "send", pack);
- __sync_add_and_fetch(&stat_PADO_sent, 1);
+ __atomic_add_fetch(&pppoe_stat.PADO_sent, 1, __ATOMIC_RELAXED);
pppoe_send(serv, pack);
}
@@ -871,7 +901,7 @@ static void pppoe_send_PADS(struct pppoe_conn_t *conn)
if (conf_verbose)
print_packet(conn->serv->ifname, "send", pack);
- __sync_add_and_fetch(&stat_PADS_sent, 1);
+ __atomic_add_fetch(&pppoe_stat.PADS_sent, 1, __ATOMIC_RELAXED);
pppoe_send(conn->serv, pack);
}
@@ -898,7 +928,7 @@ static void free_delayed_pado(struct delayed_pado_t *pado)
{
triton_timer_del(&pado->timer);
- __sync_sub_and_fetch(&stat_delayed_pado, 1);
+ __atomic_sub_fetch(&pppoe_stat.delayed_PADO, 1, __ATOMIC_RELAXED);
list_del(&pado->entry);
if (pado->host_uniq)
@@ -984,19 +1014,19 @@ static void pppoe_recv_PADI(struct pppoe_serv_t *serv, uint8_t *pack, int size)
struct timespec ts;
uint16_t ppp_max_payload = 0;
- __sync_add_and_fetch(&stat_PADI_recv, 1);
+ __atomic_add_fetch(&pppoe_stat.PADI_recv, 1, __ATOMIC_RELAXED);
if (ap_shutdown || pado_delay == -1)
return;
- if (conf_max_starting && ap_session_stat.starting >= conf_max_starting)
+ if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting)
return;
- if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions)
+ if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions)
return;
if (check_padi_limit(serv, ethhdr->h_source)) {
- __sync_add_and_fetch(&stat_PADI_drop, 1);
+ __atomic_add_fetch(&pppoe_stat.PADI_drop, 1, __ATOMIC_RELAXED);
if (conf_verbose) {
clock_gettime(CLOCK_MONOTONIC, &ts);
if (ts.tv_sec - 60 >= serv->last_padi_limit_warn) {
@@ -1017,7 +1047,7 @@ static void pppoe_recv_PADI(struct pppoe_serv_t *serv, uint8_t *pack, int size)
return;
switch (ntohs(tag->tag_type)) {
case TAG_END_OF_LIST:
- break;
+ goto tags_done;
case TAG_SERVICE_NAME:
if (tag->tag_len == 0 && conf_accept_blank_service) {
service_match = 1;
@@ -1048,6 +1078,7 @@ static void pppoe_recv_PADI(struct pppoe_serv_t *serv, uint8_t *pack, int size)
break;
}
}
+tags_done:
if (conf_verbose)
print_packet(serv->ifname, "recv", pack);
@@ -1098,7 +1129,7 @@ static void pppoe_recv_PADI(struct pppoe_serv_t *serv, uint8_t *pack, int size)
triton_timer_add(&serv->ctx, &pado->timer, 0);
list_add_tail(&pado->entry, &serv->pado_list);
- __sync_add_and_fetch(&stat_delayed_pado, 1);
+ __atomic_add_fetch(&pppoe_stat.delayed_PADO, 1, __ATOMIC_RELAXED);
} else
pppoe_send_PADO(serv, ethhdr->h_source, host_uniq_tag, relay_sid_tag, service_name_tag, ppp_max_payload);
}
@@ -1118,15 +1149,15 @@ static void pppoe_recv_PADR(struct pppoe_serv_t *serv, uint8_t *pack, int size)
int vendor_id;
uint16_t ppp_max_payload = 0;
- __sync_add_and_fetch(&stat_PADR_recv, 1);
+ __atomic_add_fetch(&pppoe_stat.PADR_recv, 1, __ATOMIC_RELAXED);
if (ap_shutdown)
return;
- if (conf_max_starting && ap_session_stat.starting >= conf_max_starting)
+ if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting)
return;
- if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions)
+ if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions)
return;
if (!memcmp(ethhdr->h_dest, bc_addr, ETH_ALEN)) {
@@ -1159,7 +1190,7 @@ static void pppoe_recv_PADR(struct pppoe_serv_t *serv, uint8_t *pack, int size)
}
switch (ntohs(tag->tag_type)) {
case TAG_END_OF_LIST:
- break;
+ goto padr_tags_done;
case TAG_SERVICE_NAME:
service_name_tag = tag;
if (tag->tag_len == 0)
@@ -1194,12 +1225,14 @@ static void pppoe_recv_PADR(struct pppoe_serv_t *serv, uint8_t *pack, int size)
if (vendor_id == VENDOR_ADSL_FORUM)
if (conf_tr101)
tr101_tag = tag;
+ break;
case TAG_PPP_MAX_PAYLOAD:
if (ntohs(tag->tag_len) == 2)
ppp_max_payload = ntohs(*(uint16_t *)tag->tag_data);
break;
}
}
+padr_tags_done:
if (!ac_cookie_tag) {
if (conf_verbose)
@@ -1207,6 +1240,12 @@ static void pppoe_recv_PADR(struct pppoe_serv_t *serv, uint8_t *pack, int size)
return;
}
+ if (!service_name_tag) {
+ if (conf_verbose)
+ log_warn("pppoe: discard PADR packet (no Service-Name tag present)\n");
+ return;
+ }
+
if (ntohs(ac_cookie_tag->tag_len) != COOKIE_LENGTH) {
if (conf_verbose)
log_warn("pppoe: discard PADR packet (incorrect AC-Cookie tag length)\n");
@@ -1229,7 +1268,7 @@ static void pppoe_recv_PADR(struct pppoe_serv_t *serv, uint8_t *pack, int size)
pthread_mutex_lock(&serv->lock);
conn = find_channel(serv, (uint8_t *)ac_cookie_tag->tag_data);
if (conn && !conn->ppp.ses.username) {
- __sync_add_and_fetch(&stat_PADR_dup_recv, 1);
+ __atomic_add_fetch(&pppoe_stat.PADR_dup_recv, 1, __ATOMIC_RELAXED);
pppoe_send_PADS(conn);
}
pthread_mutex_unlock(&serv->lock);
@@ -1368,8 +1407,12 @@ out_err:
static int __pppoe_add_interface_re(int index, int flags, const char *name, int iflink, int vid, struct iplink_arg *arg)
{
- if (pcre_exec(arg->re, NULL, name, strlen(name), 0, 0, NULL, 0) < 0)
+ pcre2_match_data *match_data = pcre2_match_data_create(0, NULL);
+ if (pcre2_match(arg->re, (PCRE2_SPTR)name, strlen(name), 0, 0, match_data, NULL) < 0) {
+ pcre2_match_data_free(match_data);
return 0;
+ }
+ pcre2_match_data_free(match_data);
__pppoe_server_start(name, arg->opt, arg->cli, iflink, vid, 0);
@@ -1378,11 +1421,11 @@ static int __pppoe_add_interface_re(int index, int flags, const char *name, int
static void pppoe_add_interface_re(const char *opt, void *cli)
{
- pcre *re = NULL;
- const char *pcre_err;
+ pcre2_code *re = NULL;
+ int pcre_err;
char *pattern;
const char *ptr;
- int pcre_offset;
+ PCRE2_SIZE pcre_offset;
struct iplink_arg arg;
for (ptr = opt; *ptr && *ptr != ','; ptr++);
@@ -1391,10 +1434,14 @@ static void pppoe_add_interface_re(const char *opt, void *cli)
memcpy(pattern, opt + 3, ptr - (opt + 3));
pattern[ptr - (opt + 3)] = 0;
- re = pcre_compile2(pattern, 0, NULL, &pcre_err, &pcre_offset, NULL);
+ re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, &pcre_err, &pcre_offset, NULL);
if (!re) {
- log_error("pppoe: %s at %i\r\n", pcre_err, pcre_offset);
+ PCRE2_UCHAR err_msg[64];
+ pcre2_get_error_message(pcre_err, err_msg, sizeof(err_msg));
+ if (cli)
+ cli_sendv(cli, "pppoe: %s at %i\r\n", err_msg, (int)pcre_offset);
+ log_error("pppoe: %s at %i\r\n", err_msg, (int)pcre_offset);
return;
}
@@ -1404,7 +1451,7 @@ static void pppoe_add_interface_re(const char *opt, void *cli)
iplink_list((iplink_list_func)__pppoe_add_interface_re, &arg);
- pcre_free(re);
+ pcre2_code_free(re);
_free(pattern);
}
@@ -1637,12 +1684,6 @@ void pppoe_server_stop(const char *ifname)
pthread_rwlock_unlock(&serv_lock);
}
-void __export pppoe_get_stat(unsigned int **starting, unsigned int **active)
-{
- *starting = &stat_starting;
- *active = &stat_active;
-}
-
static int init_secret(struct pppoe_serv_t *serv)
{
DES_cblock key;
@@ -1676,10 +1717,10 @@ void pppoe_vlan_mon_notify(int ifindex, int vid, int vlan_ifindex)
struct ifreq ifr;
char *ptr;
int len, r, svid;
- pcre *re = NULL;
- const char *pcre_err;
+ pcre2_code *re = NULL;
+ int pcre_err;
char *pattern;
- int pcre_offset;
+ PCRE2_SIZE pcre_offset;
char ifname[IFNAMSIZ];
if (!sect)
@@ -1777,15 +1818,17 @@ void pppoe_vlan_mon_notify(int ifindex, int vid, int vlan_ifindex)
memcpy(pattern, opt->val + 3, ptr - (opt->val + 3));
pattern[ptr - (opt->val + 3)] = 0;
- re = pcre_compile2(pattern, 0, NULL, &pcre_err, &pcre_offset, NULL);
+ re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, &pcre_err, &pcre_offset, NULL);
_free(pattern);
if (!re)
continue;
- r = pcre_exec(re, NULL, ifr.ifr_name, len, 0, 0, NULL, 0);
- pcre_free(re);
+ pcre2_match_data *match_data = pcre2_match_data_create(0, NULL);
+ r = pcre2_match(re, (PCRE2_SPTR)ifr.ifr_name, len, 0, 0, match_data, NULL);
+ pcre2_match_data_free(match_data);
+ pcre2_code_free(re);
if (r < 0)
continue;
@@ -1860,8 +1903,12 @@ static int __load_vlan_mon_re(int index, int flags, const char *name, int iflink
long mask1[4096/8/sizeof(long)];
struct pppoe_serv_t *serv;
- if (pcre_exec(arg->re, NULL, name, strlen(name), 0, 0, NULL, 0) < 0)
+ pcre2_match_data *match_data = pcre2_match_data_create(0, NULL);
+ if (pcre2_match(arg->re, (PCRE2_SPTR)name, strlen(name), 0, 0, match_data, NULL) < 0) {
+ pcre2_match_data_free(match_data);
return 0;
+ }
+ pcre2_match_data_free(match_data);
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, name);
@@ -1894,11 +1941,11 @@ static int __load_vlan_mon_re(int index, int flags, const char *name, int iflink
static void load_vlan_mon_re(const char *opt, long *mask, int len)
{
- pcre *re = NULL;
- const char *pcre_err;
+ pcre2_code *re = NULL;
+ int pcre_err;
char *pattern;
const char *ptr;
- int pcre_offset;
+ PCRE2_SIZE pcre_offset;
struct iplink_arg arg;
for (ptr = opt; *ptr && *ptr != ','; ptr++);
@@ -1907,10 +1954,12 @@ static void load_vlan_mon_re(const char *opt, long *mask, int len)
memcpy(pattern, opt + 3, ptr - (opt + 3));
pattern[ptr - (opt + 3)] = 0;
- re = pcre_compile2(pattern, 0, NULL, &pcre_err, &pcre_offset, NULL);
+ re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, &pcre_err, &pcre_offset, NULL);
if (!re) {
- log_error("pppoe: '%s': %s at %i\r\n", pattern, pcre_err, pcre_offset);
+ PCRE2_UCHAR err_msg[64];
+ pcre2_get_error_message(pcre_err, err_msg, sizeof(err_msg));
+ log_error("pppoe: '%s': %s at %i\r\n", pattern, err_msg, (int)pcre_offset);
return;
}
@@ -1920,7 +1969,7 @@ static void load_vlan_mon_re(const char *opt, long *mask, int len)
iplink_list((iplink_list_func)__load_vlan_mon_re, &arg);
- pcre_free(re);
+ pcre2_code_free(re);
_free(pattern);
}
diff --git a/accel-pppd/ctrl/pppoe/pppoe.h b/accel-pppd/ctrl/pppoe/pppoe.h
index 7ba4ac63..42067590 100644
--- a/accel-pppd/ctrl/pppoe/pppoe.h
+++ b/accel-pppd/ctrl/pppoe/pppoe.h
@@ -6,8 +6,10 @@
#include <linux/if.h>
#include <linux/if_pppox.h>
+#include <openssl/md5.h>
+#include <openssl/des.h>
+
#include "rbtree.h"
-#include "crypto.h"
/* PPPoE codes */
#define CODE_PADI 0x09
@@ -107,16 +109,24 @@ extern int conf_accept_any_service;
extern char *conf_ac_name;
extern char *conf_pado_delay;
-extern unsigned int stat_starting;
-extern unsigned int stat_active;
-extern unsigned int stat_delayed_pado;
-extern unsigned long stat_PADI_recv;
-extern unsigned long stat_PADO_sent;
-extern unsigned long stat_PADR_recv;
-extern unsigned long stat_PADR_dup_recv;
-extern unsigned long stat_PADS_sent;
-extern unsigned long stat_PADI_drop;
-extern unsigned long stat_filtered;
+struct pppoe_stat_t
+{
+ unsigned int starting;
+ unsigned int active;
+ unsigned int delayed_PADO;
+ unsigned long PADI_recv;
+ unsigned long PADI_drop;
+ unsigned long PADO_sent;
+ unsigned long PADR_recv;
+ unsigned long PADR_dup_recv;
+ unsigned long PADS_sent;
+ unsigned long filtered;
+};
+
+void pppoe_stat_get(struct pppoe_stat_t *stat);
+unsigned int pppoe_stat_starting(void);
+unsigned int pppoe_stat_active(void);
+void pppoe_stat_add_filtered(void);
extern pthread_rwlock_t serv_lock;
extern struct list_head serv_list;
@@ -140,4 +150,3 @@ int tr101_send_access_request(struct pppoe_tag *tr101, struct rad_packet_t *pack
int tr101_send_accounting_request(struct pppoe_tag *tr101, struct rad_packet_t *pack);
#endif
-
diff --git a/accel-pppd/ctrl/pptp/pptp.c b/accel-pppd/ctrl/pptp/pptp.c
index a95fe8ae..f8e498d6 100644
--- a/accel-pppd/ctrl/pptp/pptp.c
+++ b/accel-pppd/ctrl/pptp/pptp.c
@@ -25,6 +25,7 @@
#include "cli.h"
#include "connlimit.h"
+#include "pptp.h"
#include "memdebug.h"
@@ -55,6 +56,19 @@ struct pptp_conn_t
struct ppp_t ppp;
};
+struct pptp_stat_t
+{
+ unsigned int starting;
+ unsigned int active;
+};
+
+struct pptp_serv_t
+{
+ struct triton_context_t ctx;
+ struct triton_md_handler_t hnd;
+ struct pptp_stat_t stat;
+};
+
static int conf_ppp_max_mtu = PPTP_MAX_MTU;
static int conf_timeout = 5;
static int conf_echo_interval = 0;
@@ -69,14 +83,53 @@ static const char *conf_ifname;
static mempool_t conn_pool;
-static unsigned int stat_starting;
-static unsigned int stat_active;
-
static int pptp_read(struct triton_md_handler_t *h);
static int pptp_write(struct triton_md_handler_t *h);
static void pptp_timeout(struct triton_timer_t *);
static void ppp_started(struct ap_session *);
static void ppp_finished(struct ap_session *);
+static void pptp_ctx_switch(struct triton_context_t *ctx, void *arg);
+static int pptp_connect(struct triton_md_handler_t *h);
+static void pptp_serv_close(struct triton_context_t *ctx);
+
+static struct pptp_serv_t serv =
+{
+ .hnd.read = pptp_connect,
+ .ctx.close = pptp_serv_close,
+ .ctx.before_switch = pptp_ctx_switch,
+};
+
+static void pptp_stat_inc(unsigned int *stat)
+{
+ __atomic_add_fetch(stat, 1, __ATOMIC_RELAXED);
+}
+
+static void pptp_stat_dec(unsigned int *stat)
+{
+ __atomic_sub_fetch(stat, 1, __ATOMIC_RELAXED);
+}
+
+static void pptp_stat_move(unsigned int *from, unsigned int *to)
+{
+ pptp_stat_dec(from);
+ pptp_stat_inc(to);
+}
+
+static void pptp_stat_get(struct pptp_stat_t *stat)
+{
+ stat->starting = __atomic_load_n(&serv.stat.starting, __ATOMIC_RELAXED);
+ stat->active = __atomic_load_n(&serv.stat.active, __ATOMIC_RELAXED);
+}
+
+unsigned int __export pptp_stat_starting(void)
+{
+ return __atomic_load_n(&serv.stat.starting, __ATOMIC_RELAXED);
+}
+
+unsigned int __export pptp_stat_active(void)
+{
+ return __atomic_load_n(&serv.stat.active, __ATOMIC_RELAXED);
+}
static void pptp_ctx_switch(struct triton_context_t *ctx, void *arg)
{
@@ -101,11 +154,11 @@ static void disconnect(struct pptp_conn_t *conn)
triton_timer_del(&conn->echo_timer);
if (conn->state == STATE_PPP) {
- __sync_sub_and_fetch(&stat_active, 1);
+ pptp_stat_dec(&serv.stat.active);
conn->state = STATE_CLOSE;
ap_session_terminate(&conn->ppp.ses, TERM_LOST_CARRIER, 1);
} else if (conn->state != STATE_CLOSE)
- __sync_sub_and_fetch(&stat_starting, 1);
+ pptp_stat_dec(&serv.stat.starting);
triton_event_fire(EV_CTRL_FINISHED, &conn->ppp.ses);
@@ -142,8 +195,8 @@ again:
if (errno != EPIPE) {
if (conf_verbose)
log_ppp_info2("pptp: write: %s\n", strerror(errno));
- return -1;
}
+ return -1;
}
}
@@ -356,8 +409,7 @@ static int pptp_out_call_rqst(struct pptp_conn_t *conn)
return -1;
}
conn->state = STATE_PPP;
- __sync_sub_and_fetch(&stat_starting, 1);
- __sync_add_and_fetch(&stat_active, 1);
+ pptp_stat_move(&serv.stat.starting, &serv.stat.active);
if (conn->timeout_timer.tpd)
triton_timer_del(&conn->timeout_timer);
@@ -397,7 +449,7 @@ static int pptp_call_clear_rqst(struct pptp_conn_t *conn)
triton_timer_del(&conn->echo_timer);
if (conn->state == STATE_PPP) {
- __sync_sub_and_fetch(&stat_active, 1);
+ pptp_stat_dec(&serv.stat.active);
conn->state = STATE_CLOSE;
ap_session_terminate(&conn->ppp.ses, TERM_USER_REQUEST, 1);
}
@@ -578,7 +630,7 @@ static void pptp_close(struct triton_context_t *ctx)
{
struct pptp_conn_t *conn = container_of(ctx, typeof(*conn), ctx);
if (conn->state == STATE_PPP) {
- __sync_sub_and_fetch(&stat_active, 1);
+ pptp_stat_dec(&serv.stat.active);
conn->state = STATE_CLOSE;
ap_session_terminate(&conn->ppp.ses, TERM_ADMIN_RESET, 1);
if (send_pptp_call_disconnect_notify(conn, 3)) {
@@ -609,7 +661,7 @@ static void ppp_finished(struct ap_session *ses)
if (conn->state != STATE_CLOSE) {
log_ppp_debug("pptp: ppp finished\n");
conn->state = STATE_CLOSE;
- __sync_sub_and_fetch(&stat_active, 1);
+ pptp_stat_dec(&serv.stat.active);
if (send_pptp_call_disconnect_notify(conn, 3))
triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn);
@@ -626,12 +678,6 @@ static void ppp_finished(struct ap_session *ses)
//==================================
-struct pptp_serv_t
-{
- struct triton_context_t ctx;
- struct triton_md_handler_t hnd;
-};
-
static int pptp_connect(struct triton_md_handler_t *h)
{
struct sockaddr_in addr;
@@ -653,12 +699,12 @@ static int pptp_connect(struct triton_md_handler_t *h)
continue;
}
- if (conf_max_starting && ap_session_stat.starting >= conf_max_starting) {
+ if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting) {
close(sock);
continue;
}
- if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions) {
+ if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions) {
close(sock);
continue;
}
@@ -708,7 +754,7 @@ static int pptp_connect(struct triton_md_handler_t *h)
conn->ctrl.calling_station_id = _malloc(17);
conn->ctrl.called_station_id = _malloc(17);
u_inet_ntoa(addr.sin_addr.s_addr, conn->ctrl.calling_station_id);
- getsockname(sock, &addr, &size);
+ getsockname(sock, (struct sockaddr*)&addr, &size);
u_inet_ntoa(addr.sin_addr.s_addr, conn->ctrl.called_station_id);
ppp_init(&conn->ppp);
@@ -733,7 +779,7 @@ static int pptp_connect(struct triton_md_handler_t *h)
triton_event_fire(EV_CTRL_STARTING, &conn->ppp.ses);
- __sync_add_and_fetch(&stat_starting, 1);
+ pptp_stat_inc(&serv.stat.starting);
}
return 0;
}
@@ -744,28 +790,19 @@ static void pptp_serv_close(struct triton_context_t *ctx)
triton_context_unregister(ctx);
}
-static struct pptp_serv_t serv=
-{
- .hnd.read = pptp_connect,
- .ctx.close = pptp_serv_close,
- .ctx.before_switch = pptp_ctx_switch,
-};
-
static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
{
+ struct pptp_stat_t stat;
+
+ pptp_stat_get(&stat);
+
cli_send(client, "pptp:\r\n");
- cli_sendv(client," starting: %u\r\n", stat_starting);
- cli_sendv(client," active: %u\r\n", stat_active);
+ cli_sendv(client," starting: %u\r\n", stat.starting);
+ cli_sendv(client," active: %u\r\n", stat.active);
return CLI_CMD_OK;
}
-void __export pptp_get_stat(unsigned int **starting, unsigned int **active)
-{
- *starting = &stat_starting;
- *active = &stat_active;
-}
-
static void load_config(void)
{
char *opt;
diff --git a/accel-pppd/ctrl/pptp/pptp.h b/accel-pppd/ctrl/pptp/pptp.h
new file mode 100644
index 00000000..29f24ca2
--- /dev/null
+++ b/accel-pppd/ctrl/pptp/pptp.h
@@ -0,0 +1,7 @@
+#ifndef __PPTP_H
+#define __PPTP_H
+
+unsigned int pptp_stat_starting(void);
+unsigned int pptp_stat_active(void);
+
+#endif
diff --git a/accel-pppd/ctrl/sstp/CMakeLists.txt b/accel-pppd/ctrl/sstp/CMakeLists.txt
index 3cb1799c..3a79526f 100644
--- a/accel-pppd/ctrl/sstp/CMakeLists.txt
+++ b/accel-pppd/ctrl/sstp/CMakeLists.txt
@@ -2,6 +2,6 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
ADD_LIBRARY(sstp SHARED sstp.c)
-TARGET_LINK_LIBRARIES(sstp util)
+TARGET_LINK_LIBRARIES(sstp util ${crypto_lib})
INSTALL(TARGETS sstp LIBRARY DESTINATION lib${LIB_SUFFIX}/accel-ppp)
diff --git a/accel-pppd/ctrl/sstp/sstp.c b/accel-pppd/ctrl/sstp/sstp.c
index 2e2c4d3b..6c2b9ca9 100644
--- a/accel-pppd/ctrl/sstp/sstp.c
+++ b/accel-pppd/ctrl/sstp/sstp.c
@@ -19,10 +19,13 @@
#include <sys/stat.h>
#include "linux_ppp.h"
-#ifdef CRYPTO_OPENSSL
+/*
+ * Suppress OpenSSL 3.0 deprecation warnings for DH API.
+ * See crypto.h for detailed explanation.
+ */
+#define OPENSSL_API_COMPAT 0x10100000L
#include <openssl/ssl.h>
-#include <openssl/err.h>
-#endif
+#include <openssl/err.h>
#include "triton.h"
#include "events.h"
@@ -38,6 +41,7 @@
#include "memdebug.h"
#include "proxy_prot.h"
+#include "sstp.h"
#include "sstp_prot.h"
#ifndef min
@@ -102,9 +106,7 @@ struct buffer_t {
struct sstp_stream_t {
union {
int fd;
-#ifdef CRYPTO_OPENSSL
SSL *ssl;
-#endif
};
ssize_t (*read)(struct sstp_stream_t *stream, void *buf, size_t count);
ssize_t (*recv)(struct sstp_stream_t *stream, void *buf, size_t count, int flags);
@@ -147,16 +149,17 @@ struct sstp_conn_t {
struct ap_ctrl ctrl;
};
-static struct sstp_serv_t {
+struct sstp_serv_t {
struct triton_context_t ctx;
struct triton_md_handler_t hnd;
struct sockaddr_t addr;
-#ifdef CRYPTO_OPENSSL
SSL_CTX *ssl_ctx;
-#endif
-} serv;
+ struct sstp_stat_t stat;
+};
+
+static struct sstp_serv_t serv;
static int conf_timeout = SSTP_NEGOTIOATION_TIMEOUT;
static int conf_hello_interval = SSTP_HELLO_TIMEOUT;
@@ -176,23 +179,59 @@ static struct hash_t conf_hash_sha1 = { .len = 0 };
static struct hash_t conf_hash_sha256 = { .len = 0 };
//static int conf_bypass_auth = 0;
static const char *conf_hostname = NULL;
-static int conf_http_mode = -1;
+enum {
+ HTTP_ERR_ALLOW = -1,
+ HTTP_ERR_DENY = 0,
+ HTTP_ERR_REDIRECT = 1,
+ HTTP_ERR_REDIRECT_APPEND = 2,
+};
+static int conf_http_mode = HTTP_ERR_ALLOW;
static const char *conf_http_url = NULL;
static mempool_t conn_pool;
-static unsigned int stat_starting;
-static unsigned int stat_active;
-
static inline void sstp_queue(struct sstp_conn_t *conn, struct buffer_t *buf);
static int sstp_send(struct sstp_conn_t *conn, struct buffer_t *buf);
static inline void sstp_queue_deferred(struct sstp_conn_t *conn, struct buffer_t *buf);
+static int sstp_write(struct triton_md_handler_t *h);
static int sstp_read_deferred(struct sstp_conn_t *conn);
static int sstp_abort(struct sstp_conn_t *conn, int disconnect);
static void sstp_disconnect(struct sstp_conn_t *conn);
static int sstp_handler(struct sstp_conn_t *conn, struct buffer_t *buf);
static int http_handler(struct sstp_conn_t *conn, struct buffer_t *buf);
+void __export sstp_stat_get(struct sstp_stat_t *stat)
+{
+ stat->starting = __atomic_load_n(&serv.stat.starting, __ATOMIC_RELAXED);
+ stat->active = __atomic_load_n(&serv.stat.active, __ATOMIC_RELAXED);
+}
+
+unsigned int __export sstp_stat_starting(void)
+{
+ return __atomic_load_n(&serv.stat.starting, __ATOMIC_RELAXED);
+}
+
+unsigned int __export sstp_stat_active(void)
+{
+ return __atomic_load_n(&serv.stat.active, __ATOMIC_RELAXED);
+}
+
+static void sstp_stat_inc(unsigned int *stat)
+{
+ __atomic_add_fetch(stat, 1, __ATOMIC_RELAXED);
+}
+
+static void sstp_stat_dec(unsigned int *stat)
+{
+ __atomic_sub_fetch(stat, 1, __ATOMIC_RELAXED);
+}
+
+static void sstp_stat_move(unsigned int *from, unsigned int *to)
+{
+ sstp_stat_dec(from);
+ sstp_stat_inc(to);
+}
+
/*
* FCS lookup table as calculated by genfcstab.
*/
@@ -489,7 +528,6 @@ static struct sstp_stream_t *stream_init(int fd)
/* ssl stream */
-#ifdef CRYPTO_OPENSSL
static ssize_t ssl_stream_read(struct sstp_stream_t *stream, void *buf, size_t count)
{
int ret, err;
@@ -585,7 +623,6 @@ error:
ssl_stream_free(stream);
return NULL;
}
-#endif
/* proxy */
@@ -858,7 +895,7 @@ static int http_send_response(struct sstp_conn_t *conn, char *proto, char *statu
}
}
- return sstp_send(conn, buf);
+ return sstp_send(conn, buf) || sstp_write(&conn->hnd);
}
static int http_recv_request(struct sstp_conn_t *conn, uint8_t *data, int len)
@@ -879,17 +916,17 @@ static int http_recv_request(struct sstp_conn_t *conn, uint8_t *data, int len)
log_ppp_info2("recv [HTTP <%s>]\n", line);
if (vstrsep(line, " ", &method, &request, &proto) < 3) {
- if (conf_http_mode)
+ if (conf_http_mode != HTTP_ERR_DENY)
http_send_response(conn, "HTTP/1.1", "400 Bad Request", NULL);
return -1;
}
if (strncasecmp(proto, "HTTP/1", sizeof("HTTP/1") - 1) != 0) {
- if (conf_http_mode)
+ if (conf_http_mode != HTTP_ERR_DENY)
http_send_response(conn, "HTTP/1.1", "400 Bad Request", NULL);
return -1;
}
if (strcasecmp(method, SSTP_HTTP_METHOD) != 0 && strcasecmp(method, "GET") != 0) {
- if (conf_http_mode)
+ if (conf_http_mode != HTTP_ERR_DENY)
http_send_response(conn, proto, "501 Not Implemented", NULL);
return -1;
}
@@ -911,7 +948,7 @@ static int http_recv_request(struct sstp_conn_t *conn, uint8_t *data, int len)
}
if (host_error) {
- if (conf_http_mode)
+ if (conf_http_mode != HTTP_ERR_DENY)
http_send_response(conn, proto, "404 Not Found", NULL);
return -1;
}
@@ -919,11 +956,11 @@ static int http_recv_request(struct sstp_conn_t *conn, uint8_t *data, int len)
if (strcasecmp(method, SSTP_HTTP_METHOD) != 0 || strcasecmp(request, SSTP_HTTP_URI) != 0) {
if (conf_http_mode > 0) {
if (_asprintf(&line, "Location: %s%s\r\n",
- conf_http_url, (conf_http_mode == 2) ? request : "") < 0)
+ conf_http_url, (conf_http_mode == HTTP_ERR_REDIRECT_APPEND) ? request : "") < 0)
return -1;
http_send_response(conn, proto, "301 Moved Permanently", line);
_free(line);
- } else if (conf_http_mode < 0)
+ } else if (conf_http_mode == HTTP_ERR_ALLOW)
http_send_response(conn, proto, "404 Not Found", NULL);
return -1;
}
@@ -937,7 +974,7 @@ static int http_handler(struct sstp_conn_t *conn, struct buffer_t *buf)
static const char *table[] = { "\n\r\n", "\r\r\n", NULL };
const char **pptr;
uint8_t *ptr, *end = NULL;
- int n;
+ int n, r;
if (conn->sstp_state != STATE_SERVER_CALL_DISCONNECTED)
return -1;
@@ -963,8 +1000,11 @@ static int http_handler(struct sstp_conn_t *conn, struct buffer_t *buf)
} else
n = end - buf->head;
- if (http_recv_request(conn, buf->head, n) < 0)
+ r = http_recv_request(conn, buf->head, n);
+ if (r < 0)
return -1;
+ else if (r > 0)
+ return 1;
buf_pull(buf, n);
conn->sstp_state = STATE_SERVER_CONNECT_REQUEST_PENDING;
@@ -1200,7 +1240,7 @@ static int ppp_write(struct triton_md_handler_t *h)
ssize_t n;
int i;
- if (!list_empty(&conn->ppp_queue)) {
+ while (!list_empty(&conn->ppp_queue)) {
i = n = 0;
list_for_each_entry(buf, &conn->ppp_queue, entry) {
if (i < PPP_BUF_IOVEC && n < PPP_BUF_SIZE) {
@@ -1232,9 +1272,6 @@ static int ppp_write(struct triton_md_handler_t *h)
list_del(&buf->entry);
free_buf(buf);
} while (n > 0);
-
- if (!list_empty(&conn->ppp_queue))
- goto defer;
}
triton_md_disable_handler(h, MD_MODE_WRITE);
return 0;
@@ -1500,8 +1537,7 @@ static int sstp_recv_msg_call_connect_request(struct sstp_conn_t *conn, struct s
goto error;
conn->sstp_state = STATE_SERVER_CALL_CONNECTED_PENDING;
- __sync_sub_and_fetch(&stat_starting, 1);
- __sync_add_and_fetch(&stat_active, 1);
+ sstp_stat_move(&serv.stat.starting, &serv.stat.active);
triton_event_fire(EV_CTRL_STARTED, &conn->ppp.ses);
conn->ppp_state = STATE_STARTING;
@@ -1528,12 +1564,10 @@ static int sstp_recv_msg_call_connected(struct sstp_conn_t *conn, struct sstp_ct
uint8_t hash;
unsigned int len;
struct npioctl np;
-#ifdef CRYPTO_OPENSSL
typeof(*msg) buf;
uint8_t md[EVP_MAX_MD_SIZE], *ptr;
const EVP_MD *evp;
unsigned int mdlen;
-#endif
if (conf_verbose)
log_ppp_info2("recv [SSTP SSTP_MSG_CALL_CONNECTED]\n");
@@ -1571,9 +1605,7 @@ static int sstp_recv_msg_call_connected(struct sstp_conn_t *conn, struct sstp_ct
log_ppp_error("sstp: invalid SHA256 Cert Hash\n");
return sstp_abort(conn, 0);
}
-#ifdef CRYPTO_OPENSSL
evp = EVP_sha256();
-#endif
} else if (hash & CERT_HASH_PROTOCOL_SHA1) {
len = SHA_DIGEST_LENGTH;
if (conf_hash_sha1.len == len &&
@@ -1581,9 +1613,7 @@ static int sstp_recv_msg_call_connected(struct sstp_conn_t *conn, struct sstp_ct
log_ppp_error("sstp: invalid SHA1 Cert Hash\n");
return sstp_abort(conn, 0);
}
-#ifdef CRYPTO_OPENSSL
evp = EVP_sha1();
-#endif
} else {
log_ppp_error("sstp: invalid Hash Protocol 0x%02x\n",
msg->attr.hash_protocol_bitmask);
@@ -1608,7 +1638,6 @@ static int sstp_recv_msg_call_connected(struct sstp_conn_t *conn, struct sstp_ct
return 0;
}
-#ifdef CRYPTO_OPENSSL
ptr = mempcpy(md, SSTP_CMK_SEED, SSTP_CMK_SEED_SIZE);
*ptr++ = len;
*ptr++ = 0;
@@ -1624,7 +1653,6 @@ static int sstp_recv_msg_call_connected(struct sstp_conn_t *conn, struct sstp_ct
log_ppp_error("sstp: invalid Compound MAC\n");
return sstp_abort(conn, 0);
}
-#endif
}
if (conn->timeout_timer.tpd)
@@ -1818,7 +1846,7 @@ static int sstp_recv_data_packet(struct sstp_conn_t *conn, struct sstp_hdr *hdr)
buf_put_data(buf, hdr->data, size);
#else
- buf = alloc_buf(size*2 + 2 + PPP_FCSLEN);
+ buf = alloc_buf(size*2 + 2 + PPP_FCSLEN*2);
if (!buf) {
log_error("sstp: no memory\n");
return -1;
@@ -1950,6 +1978,8 @@ static int sstp_read(struct triton_md_handler_t *h)
n = conn->handler(conn, buf);
if (n < 0)
goto drop;
+ else if (n > 0)
+ return 1;
buf_expand_tail(buf, SSTP_MAX_PACKET_SIZE);
}
@@ -2208,17 +2238,17 @@ static void sstp_disconnect(struct sstp_conn_t *conn)
switch (conn->ppp_state) {
case STATE_INIT:
- __sync_sub_and_fetch(&stat_starting, 1);
+ sstp_stat_dec(&serv.stat.starting);
break;
case STATE_STARTING:
case STATE_AUTHORIZED:
case STATE_STARTED:
conn->ppp_state = STATE_FINISHED;
- __sync_sub_and_fetch(&stat_active, 1);
+ sstp_stat_dec(&serv.stat.active);
ap_session_terminate(&conn->ppp.ses, TERM_LOST_CARRIER, 1);
break;
case STATE_FINISHED:
- __sync_sub_and_fetch(&stat_active, 1);
+ sstp_stat_dec(&serv.stat.active);
break;
}
triton_event_fire(EV_CTRL_FINISHED, &conn->ppp.ses);
@@ -2254,11 +2284,9 @@ static void sstp_start(struct sstp_conn_t *conn)
{
log_debug("sstp: starting\n");
-#ifdef CRYPTO_OPENSSL
if (serv.ssl_ctx)
conn->stream = ssl_stream_init(conn->hnd.fd, serv.ssl_ctx);
else
-#endif
conn->stream = stream_init(conn->hnd.fd);
if (!conn->stream) {
log_error("sstp: stream open error: %s\n", strerror(errno));
@@ -2299,12 +2327,12 @@ static int sstp_connect(struct triton_md_handler_t *h)
continue;
}
- if (conf_max_starting && ap_session_stat.starting >= conf_max_starting) {
+ if (conf_max_starting && ap_session_stat_starting() >= conf_max_starting) {
close(sock);
continue;
}
- if (conf_max_sessions && ap_session_stat.active + ap_session_stat.starting >= conf_max_sessions) {
+ if (conf_max_sessions && ap_session_stat_active() + ap_session_stat_starting() >= conf_max_sessions) {
close(sock);
continue;
}
@@ -2425,7 +2453,7 @@ static int sstp_connect(struct triton_md_handler_t *h)
triton_event_fire(EV_CTRL_STARTING, &conn->ppp.ses);
- __sync_add_and_fetch(&stat_starting, 1);
+ sstp_stat_inc(&serv.stat.starting);
}
return 0;
@@ -2438,17 +2466,14 @@ static void sstp_serv_close(struct triton_context_t *ctx)
triton_md_unregister_handler(&serv->hnd, 1);
triton_context_unregister(ctx);
-#ifdef CRYPTO_OPENSSL
if (serv->ssl_ctx)
SSL_CTX_free(serv->ssl_ctx);
serv->ssl_ctx = NULL;
-#endif
if (serv->addr.u.sa.sa_family == AF_UNIX && serv->addr.u.sun.sun_path[0])
unlink(serv->addr.u.sun.sun_path);
}
-#ifdef CRYPTO_OPENSSL
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
static int ssl_servername(SSL *ssl, int *al, void *arg)
{
@@ -2482,6 +2507,13 @@ static void ssl_info_cb(const SSL *ssl, int where, int ret)
#endif
#endif
+static void ssl_set_cert_hashes(const X509 *cert) {
+ if (conf_hash_protocol & CERT_HASH_PROTOCOL_SHA1)
+ X509_digest(cert, EVP_sha1(), conf_hash_sha1.hash, &conf_hash_sha1.len);
+ if (conf_hash_protocol & CERT_HASH_PROTOCOL_SHA256)
+ X509_digest(cert, EVP_sha256(), conf_hash_sha256.hash, &conf_hash_sha256.len);
+}
+
static void ssl_load_config(struct sstp_serv_t *serv, const char *servername)
{
SSL_CTX *old_ctx, *ssl_ctx = NULL;
@@ -2489,26 +2521,6 @@ static void ssl_load_config(struct sstp_serv_t *serv, const char *servername)
BIO *in = NULL;
char *opt;
- opt = conf_get_opt("sstp", "ssl-pemfile");
- if (opt) {
- in = BIO_new(BIO_s_file());
- if (!in) {
- log_error("sstp: %s error: %s\n", "ssl-pemfile", ERR_error_string(ERR_get_error(), NULL));
- goto error;
- }
-
- if (BIO_read_filename(in, opt) <= 0) {
- log_error("sstp: %s error: %s\n", "ssl-pemfile", ERR_error_string(ERR_get_error(), NULL));
- goto error;
- }
-
- cert = PEM_read_bio_X509(in, NULL, NULL, NULL);
- if (!cert) {
- log_error("sstp: %s error: %s\n", "ssl-pemfile", ERR_error_string(ERR_get_error(), NULL));
- goto error;
- }
- }
-
opt = conf_get_opt("sstp", "accept");
if (opt && strhas(opt, "ssl", ',')) {
legacy_ssl:
@@ -2601,6 +2613,8 @@ static void ssl_load_config(struct sstp_serv_t *serv, const char *servername)
#else
DH *dh;
+ in = BIO_new(BIO_s_file());
+
if (BIO_read_filename(in, opt) <= 0) {
log_error("sstp: %s error: %s\n", "ssl-dhparam", ERR_error_string(ERR_get_error(), NULL));
goto error;
@@ -2612,6 +2626,10 @@ static void ssl_load_config(struct sstp_serv_t *serv, const char *servername)
goto error;
}
+ if (!BIO_free(in))
+ abort();
+ in = NULL;
+
SSL_CTX_set_tmp_dh(ssl_ctx, dh);
DH_free(dh);
#endif
@@ -2664,12 +2682,21 @@ static void ssl_load_config(struct sstp_serv_t *serv, const char *servername)
if (opt && atoi(opt))
SSL_CTX_set_options(ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
- if (cert && SSL_CTX_use_certificate(ssl_ctx, cert) != 1) {
- log_error("sstp: %s error: %s\n", "ssl-pemfile", ERR_error_string(ERR_get_error(), NULL));
- goto error;
+ opt = conf_get_opt("sstp", "ssl-pemfile");
+ if (opt) {
+ if (SSL_CTX_use_certificate_chain_file(ssl_ctx, opt) != 1) {
+ log_error("sstp: %s error: %s\n", "ssl-pemfile", ERR_error_string(ERR_get_error(), NULL));
+ goto error;
+ }
+ // cert is a reference. Do not free it.
+ X509 *cert_ref = SSL_CTX_get0_certificate(ssl_ctx);
+ if (!cert_ref) {
+ log_error("sstp: %s error: %s\n", "ssl-pemfile", ERR_error_string(ERR_get_error(), NULL));
+ goto error;
+ }
+ ssl_set_cert_hashes(cert_ref);
}
-
- opt = conf_get_opt("sstp", "ssl-keyfile") ? : conf_get_opt("sstp", "ssl-pemfile");
+ opt = conf_get_opt("sstp", "ssl-keyfile") ? : opt;
if ((opt && SSL_CTX_use_PrivateKey_file(ssl_ctx, opt, SSL_FILETYPE_PEM) != 1) ||
SSL_CTX_check_private_key(ssl_ctx) != 1) {
log_error("sstp: %s error: %s\n", "ssl-keyfile", ERR_error_string(ERR_get_error(), NULL));
@@ -2697,13 +2724,30 @@ static void ssl_load_config(struct sstp_serv_t *serv, const char *servername)
opt = conf_get_opt("sstp", "ssl");
if (opt && atoi(opt) > 0)
goto legacy_ssl;
- }
- if (cert) {
- if (conf_hash_protocol & CERT_HASH_PROTOCOL_SHA1)
- X509_digest(cert, EVP_sha1(), conf_hash_sha1.hash, &conf_hash_sha1.len);
- if (conf_hash_protocol & CERT_HASH_PROTOCOL_SHA256)
- X509_digest(cert, EVP_sha256(), conf_hash_sha256.hash, &conf_hash_sha256.len);
+ opt = conf_get_opt("sstp", "ssl-pemfile");
+ if (opt) {
+ in = BIO_new(BIO_s_file());
+ if (!in) {
+ log_error("sstp: %s error: %s\n", "ssl-pemfile", ERR_error_string(ERR_get_error(), NULL));
+ goto error;
+ }
+
+ if (BIO_read_filename(in, opt) <= 0) {
+ log_error("sstp: %s error: %s\n", "ssl-pemfile", ERR_error_string(ERR_get_error(), NULL));
+ goto error;
+ }
+
+ cert = PEM_read_bio_X509(in, NULL, NULL, NULL);
+ if (!cert) {
+ log_error("sstp: %s error: %s\n", "ssl-pemfile", ERR_error_string(ERR_get_error(), NULL));
+ goto error;
+ }
+ if (!BIO_free(in))
+ abort();
+ in = NULL;
+ ssl_set_cert_hashes(cert);
+ }
}
old_ctx = serv->ssl_ctx;
@@ -2715,10 +2759,9 @@ error:
SSL_CTX_free(ssl_ctx);
if (cert)
X509_free(cert);
- if (in)
- BIO_free(in);
+ if (in && !BIO_free(in))
+ abort();
}
-#endif
static void ev_mppe_keys(struct ev_mppe_keys_t *ev)
{
@@ -2752,19 +2795,17 @@ static void ev_ses_authorized(struct ap_session *ses)
static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
{
+ struct sstp_stat_t stat;
+
+ sstp_stat_get(&stat);
+
cli_send(client, "sstp:\r\n");
- cli_sendv(client," starting: %u\r\n", stat_starting);
- cli_sendv(client," active: %u\r\n", stat_active);
+ cli_sendv(client," starting: %u\r\n", stat.starting);
+ cli_sendv(client," active: %u\r\n", stat.active);
return CLI_CMD_OK;
}
-void __export sstp_get_stat(unsigned int **starting, unsigned int **active)
-{
- *starting = &stat_starting;
- *active = &stat_active;
-}
-
static void load_config(void)
{
int ipmode;
@@ -2779,15 +2820,15 @@ static void load_config(void)
opt = conf_get_opt("sstp", "http-error");
if (opt) {
if (strcmp(opt, "deny") == 0)
- conf_http_mode = 0;
+ conf_http_mode = HTTP_ERR_DENY;
else if (strcmp(opt, "allow") == 0)
- conf_http_mode = -1;
+ conf_http_mode = HTTP_ERR_ALLOW;
else if (strstr(opt, "://") != NULL) {
conf_http_url = opt;
opt = strstr(opt, "://") + 3;
while (*opt == '/')
opt++;
- conf_http_mode = strchr(opt, '/') ? 1 : 2;
+ conf_http_mode = strchr(opt, '/') ? HTTP_ERR_REDIRECT : HTTP_ERR_REDIRECT_APPEND;
}
}
@@ -2803,12 +2844,9 @@ static void load_config(void)
opt = conf_get_opt("sstp", "accept");
conf_proxyproto = opt && strhas(opt, "proxy", ',');
-#ifdef CRYPTO_OPENSSL
ssl_load_config(&serv, conf_hostname);
opt = serv.ssl_ctx ? "enabled" : "disabled";
-#else
- opt = "not available";
-#endif
+
if (conf_verbose) {
log_info2("sstp: SSL/TLS support %s, PROXY support %s\n",
opt, conf_proxyproto ? "enabled" : "disabled");
diff --git a/accel-pppd/ctrl/sstp/sstp.h b/accel-pppd/ctrl/sstp/sstp.h
new file mode 100644
index 00000000..eff8e053
--- /dev/null
+++ b/accel-pppd/ctrl/sstp/sstp.h
@@ -0,0 +1,14 @@
+#ifndef __SSTP_H
+#define __SSTP_H
+
+struct sstp_stat_t
+{
+ unsigned int starting;
+ unsigned int active;
+};
+
+void sstp_stat_get(struct sstp_stat_t *stat);
+unsigned int sstp_stat_starting(void);
+unsigned int sstp_stat_active(void);
+
+#endif