summaryrefslogtreecommitdiff
path: root/accel-pppd
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pppd')
-rw-r--r--accel-pppd/accel-ppp.conf4
-rw-r--r--accel-pppd/accel-ppp.conf.512
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c28
-rw-r--r--accel-pppd/ctrl/sstp/sstp.c101
-rw-r--r--accel-pppd/ipv6/dhcpv6.c5
-rw-r--r--accel-pppd/ipv6/dhcpv6.h21
-rw-r--r--accel-pppd/ipv6/dhcpv6_packet.c99
-rw-r--r--accel-pppd/main.c6
-rw-r--r--accel-pppd/ppp/ipcp_opt_ipaddr.c11
-rw-r--r--accel-pppd/radius/acct.c2
-rw-r--r--accel-pppd/shaper/shaper.c36
11 files changed, 274 insertions, 51 deletions
diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf
index 929402b..1db492f 100644
--- a/accel-pppd/accel-ppp.conf
+++ b/accel-pppd/accel-ppp.conf
@@ -40,6 +40,7 @@ thread-count=4
#sid-case=upper
#sid-source=seq
#max-sessions=1000
+#check-ip=0
[ppp]
verbose=1
@@ -49,7 +50,6 @@ mru=1400
#accomp=deny
#pcomp=deny
#ccp=0
-#check-ip=0
#mppe=require
ipv4=require
ipv6=deny
@@ -112,6 +112,7 @@ verbose=1
#cert-hash-sha1=
#cert-hash-sha256=
#accept=ssl,proxy
+#ssl-protocol=tls1,tls1.1,tls1.2,tls1.3
#ssl-dhparam=/etc/ssl/dhparam.pem
#ssl-ecdh-curve=prime256v1
#ssl-ciphers=DEFAULT
@@ -264,6 +265,7 @@ down-limiter=tbf
#leaf-qdisc=fq_codel [limit PACKETS] [flows NUMBER] [target TIME] [interval TIME] [quantum BYTES] [[no]ecn]
#rate-multiplier=1
#fwmark=1
+#rate-limit=2048/1024
verbose=1
[cli]
diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5
index 15becb3..6533ef5 100644
--- a/accel-pppd/accel-ppp.conf.5
+++ b/accel-pppd/accel-ppp.conf.5
@@ -122,6 +122,9 @@ Path to file for sessions sequence number. Start sequence number may be set ther
.TP
.BI "max-sessions=" n
Specifies maximum sessions which server may processed (default 0, disabled)
+.TP
+.BI "check-ip=" 0|1
+Specifies whether accel-ppp should check if IP already assigned to other ppp interface (default 0).
.SH [ppp]
.br
PPP module configuration.
@@ -159,9 +162,6 @@ Protocol field compression negotiation.
.BI "ccp=" n
Disable CCP negotiation if this parameter is zero.
.TP
-.BI "check-ip=" 0|1
-Specifies whether accel-ppp should check if IP already assigned to other ppp interface (default 0).
-.TP
.BI "mppe=" require|prefer|deny
Specifies mppe negotiation preference.
.br
@@ -715,6 +715,9 @@ Specifies incoming connection acceptance mode.
.B proxy
- enable PROXY protocol 1 & 2 support.
.TP
+.BI "ssl-protocol=" ssl2|ssl3|tls1|tls1.1|tls1.2|tls1.3
+Specifies the enabled SSL/TLS protocols supported by OpenSSL library.
+.TP
.BI "ssl-dhparam=" pemfile
Specifies a file with DH parameters for DHE ciphers.
.TP
@@ -1102,6 +1105,9 @@ fq_codel [ limit PACKETS ] [flows NUMBER ] [ target TIME ] [ interval TIME ] [qu
.TP
.BI "rate-multiplier=" n
Due to accel-ppp operates with rates in kilobit basis if you send rates in different basis then you can use this option to bring your values to kilobits.
+.TP
+.BI "rate-limit=" download_speed/upload_speed
+Specifies, should accel-ppp set default rate-limit for clients. Clients rate-limit will be overwritten by RADIUS filter attributes or chap-secrets rate-limit params.
.SH [cli]
.br
Configuration of the command line interface.
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index 5438b61..9880162 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -107,6 +107,7 @@ struct local_net {
enum {SID_MAC, SID_IP};
+static int conf_check_exists;
static int conf_dhcpv4 = 1;
static int conf_up;
static int conf_auto;
@@ -577,6 +578,24 @@ static int ipoe_create_interface(struct ipoe_session *ses)
return 0;
}
+static int check_exists(struct ipoe_session *self_ipoe, in_addr_t addr)
+{
+ struct ap_session *ses;
+ int r = 0;
+
+ pthread_rwlock_rdlock(&ses_lock);
+ list_for_each_entry(ses, &ses_list, entry) {
+ if (!ses->terminating && ses->ipv4 && ses->ipv4->peer_addr == addr && ses != &self_ipoe->ses) {
+ log_ppp_warn("ipoe: IPv4 address already assigned to %s\n", ses->ifname);
+ r = 1;
+ break;
+ }
+ }
+ pthread_rwlock_unlock(&ses_lock);
+
+ return r;
+}
+
static void auth_result(struct ipoe_session *ses, int r)
{
char *username = ses->username;
@@ -617,6 +636,11 @@ static void auth_result(struct ipoe_session *ses, int r)
ap_session_set_username(&ses->ses, username);
log_ppp_info1("%s: authentication succeeded\n", ses->ses.username);
+ if (conf_check_exists && check_exists(ses, ses->yiaddr)){
+ ap_session_terminate(&ses->ses, TERM_NAS_REQUEST, 1);
+ return;
+ }
+
cont:
triton_event_fire(EV_SES_AUTHORIZED, &ses->ses);
@@ -3930,6 +3954,10 @@ static void load_config(void)
else
conf_weight = 0;
+ opt = conf_get_opt("common", "check-ip");
+ if (opt && atoi(opt) >= 0)
+ conf_check_exists = atoi(opt) > 0;
+
#ifdef RADIUS
if (triton_module_loaded("radius"))
load_radius_attrs();
diff --git a/accel-pppd/ctrl/sstp/sstp.c b/accel-pppd/ctrl/sstp/sstp.c
index 0e991bc..62e574c 100644
--- a/accel-pppd/ctrl/sstp/sstp.c
+++ b/accel-pppd/ctrl/sstp/sstp.c
@@ -2362,18 +2362,18 @@ static void ssl_load_config(struct sstp_serv_t *serv, const char *servername)
if (opt) {
in = BIO_new(BIO_s_file());
if (!in) {
- log_error("sstp: SSL certificate error: %s\n", ERR_error_string(ERR_get_error(), NULL));
+ 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: SSL certificate error: %s\n", ERR_error_string(ERR_get_error(), NULL));
+ 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: SSL certificate error: %s\n", ERR_error_string(ERR_get_error(), NULL));
+ log_error("sstp: %s error: %s\n", "ssl-pemfile", ERR_error_string(ERR_get_error(), NULL));
goto error;
}
}
@@ -2381,17 +2381,13 @@ static void ssl_load_config(struct sstp_serv_t *serv, const char *servername)
opt = conf_get_opt("sstp", "accept");
if (opt && strhas(opt, "ssl", ',')) {
legacy_ssl:
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
- ssl_ctx = SSL_CTX_new(TLS_server_method());
-#else
ssl_ctx = SSL_CTX_new(SSLv23_server_method());
-#endif
if (!ssl_ctx) {
- log_error("sstp: SSL_CTX error: %s\n", ERR_error_string(ERR_get_error(), NULL));
+ log_error("sstp: %s error: %s\n", "SSL_CTX_new", ERR_error_string(ERR_get_error(), NULL));
goto error;
}
- SSL_CTX_set_options(ssl_ctx,
+ SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL |
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS |
#endif
@@ -2404,37 +2400,98 @@ static void ssl_load_config(struct sstp_serv_t *serv, const char *servername)
#ifndef OPENSSL_NO_ECDH
SSL_OP_SINGLE_ECDH_USE |
#endif
+#ifdef OPENSSL_NO_SSL2
SSL_OP_NO_SSLv2 |
+#endif
+#ifdef OPENSSL_NO_SSL3
SSL_OP_NO_SSLv3 |
+#endif
SSL_OP_NO_COMPRESSION);
SSL_CTX_set_mode(ssl_ctx,
SSL_MODE_ENABLE_PARTIAL_WRITE |
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
SSL_CTX_set_read_ahead(ssl_ctx, 1);
-#ifndef OPENSSL_NO_DH
+ opt = conf_get_opt("sstp", "ssl-protocol");
+ if (opt) {
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ SSL_CTX_set_min_proto_version(ssl_ctx, 0);
+ SSL_CTX_set_max_proto_version(ssl_ctx, 0);
+#endif
+ if (strhas(opt, "ssl2", ','))
+#if defined(OPENSSL_NO_SSL2) || OPENSSL_VERSION_NUMBER >= 0x10100000L
+ log_warn("sstp: %s warning: %s is not suported\n", "ssl-protocol", "SSLv2");
+#else
+ SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_SSLv2);
+ else
+ SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2);
+#endif
+ if (strhas(opt, "ssl3", ','))
+#ifdef OPENSSL_NO_SSL3
+ log_warn("sstp: %s warning: %s is not suported\n", "ssl-protocol", "SSLv3");
+#else
+ SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_SSLv3);
+ else
+ SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv3);
+#endif
+ if (strhas(opt, "tls1", ','))
+ SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_TLSv1);
+ else
+ SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1);
+ if (strhas(opt, "tls11", ',') || strhas(opt, "tls1.1", ','))
+#ifndef SSL_OP_NO_TLSv1_1
+ log_warn("sstp: %s warning: %s is not suported\n", "ssl-protocol", "TLSv1.1");
+#else
+ SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_TLSv1_1);
+ else
+ SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_1);
+#endif
+ if (strhas(opt, "tls12", ',') || strhas(opt, "tls1.2", ','))
+#ifndef SSL_OP_NO_TLSv1_2
+ log_warn("sstp: %s warning: %s is not suported\n", "ssl-protocol", "TLSv1.2");
+#else
+ SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_TLSv1_2);
+ else
+ SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_2);
+#endif
+ if (strhas(opt, "tls13", ',') || strhas(opt, "tls1.3", ','))
+#ifndef SSL_OP_NO_TLSv1_3
+ log_warn("sstp: %s warning: %s is not suported\n", "ssl-protocol", "TLSv1.3");
+#else
+ SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_TLSv1_3);
+ else
+ SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_3);
+#endif
+ }
+
opt = conf_get_opt("sstp", "ssl-dhparam");
if (opt) {
+#ifdef OPENSSL_NO_DH
+ log_warn("sstp: %s warning: %s is not suported\n", "ssl-protocol", "DH");
+#else
DH *dh;
if (BIO_read_filename(in, opt) <= 0) {
- log_error("sstp: SSL dhparam error: %s\n", ERR_error_string(ERR_get_error(), NULL));
+ log_error("sstp: %s error: %s\n", "ssl-dhparam", ERR_error_string(ERR_get_error(), NULL));
goto error;
}
dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
if (dh == NULL) {
- log_error("sstp: SSL dhparam error: %s\n", ERR_error_string(ERR_get_error(), NULL));
+ log_error("sstp: %s error: %s\n", "ssl-dhparam", ERR_error_string(ERR_get_error(), NULL));
goto error;
}
SSL_CTX_set_tmp_dh(ssl_ctx, dh);
DH_free(dh);
- }
#endif
+ }
-#ifndef OPENSSL_NO_ECDH
opt = conf_get_opt("sstp", "ssl-ecdh-curve");
+#ifdef OPENSSL_NO_ECDH
+ if (opt)
+ log_warn("sstp: %s warning: %s is not suported\n", "ssl-protocol", "ECDH");
+#else
{
#if defined(SSL_CTX_set1_curves_list) || defined(SSL_CTRL_SET_CURVES_LIST)
#ifdef SSL_CTRL_SET_ECDH_AUTO
@@ -2442,7 +2499,7 @@ static void ssl_load_config(struct sstp_serv_t *serv, const char *servername)
SSL_CTX_set_ecdh_auto(ssl_ctx, 1);
#endif
if (opt && SSL_CTX_set1_curves_list(ssl_ctx, opt) == 0) {
- log_error("sstp: SSL ecdh-curve error: %s\n", ERR_error_string(ERR_get_error(), NULL));
+ log_error("sstp: %s error: %s\n", "ssl-ecdh-curve", ERR_error_string(ERR_get_error(), NULL));
goto error;
}
#else
@@ -2451,13 +2508,13 @@ static void ssl_load_config(struct sstp_serv_t *serv, const char *servername)
nid = OBJ_sn2nid(opt ? : "prime256v1");
if (nid == 0) {
- log_error("sstp: SSL ecdh-curve error: %s\n", ERR_error_string(ERR_get_error(), NULL));
+ log_error("sstp: %s error: %s\n", "ssl-ecdh-curve", ERR_error_string(ERR_get_error(), NULL));
goto error;
}
ecdh = EC_KEY_new_by_curve_name(nid);
if (ecdh == NULL) {
- log_error("sstp: SSL ecdh-curve error: %s\n", ERR_error_string(ERR_get_error(), NULL));
+ log_error("sstp: %s error: %s\n", "ssl-ecdh-curve", ERR_error_string(ERR_get_error(), NULL));
goto error;
}
@@ -2469,7 +2526,7 @@ static void ssl_load_config(struct sstp_serv_t *serv, const char *servername)
opt = conf_get_opt("sstp", "ssl-ciphers");
if (opt && SSL_CTX_set_cipher_list(ssl_ctx, opt) != 1) {
- log_error("sstp: SSL cipher list error: %s\n", ERR_error_string(ERR_get_error(), NULL));
+ log_error("sstp: %s error: %s\n", "ssl-ciphers", ERR_error_string(ERR_get_error(), NULL));
goto error;
}
@@ -2478,26 +2535,26 @@ static void ssl_load_config(struct sstp_serv_t *serv, const char *servername)
SSL_CTX_set_options(ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
if (cert && SSL_CTX_use_certificate(ssl_ctx, cert) != 1) {
- log_error("sstp: SSL certificate error: %s\n", ERR_error_string(ERR_get_error(), NULL));
+ log_error("sstp: %s error: %s\n", "ssl-pemfile", ERR_error_string(ERR_get_error(), NULL));
goto error;
}
opt = conf_get_opt("sstp", "ssl-keyfile") ? : conf_get_opt("sstp", "ssl-pemfile");
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: SSL private key error: %s\n", ERR_error_string(ERR_get_error(), NULL));
+ log_error("sstp: %s error: %s\n", "ssl-keyfile", ERR_error_string(ERR_get_error(), NULL));
goto error;
}
opt = conf_get_opt("sstp", "ssl-ca-file");
if (opt && SSL_CTX_load_verify_locations(ssl_ctx, opt, NULL) != 1) {
- log_error("sstp: SSL ca file error: %s\n", ERR_error_string(ERR_get_error(), NULL));
+ log_error("sstp: %s error: %s\n", "ssl-ca-file", ERR_error_string(ERR_get_error(), NULL));
goto error;
}
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
if (servername && SSL_CTX_set_tlsext_servername_callback(ssl_ctx, ssl_servername) != 1)
- log_warn("sstp: SSL server name check error: %s\n", ERR_error_string(ERR_get_error(), NULL));
+ log_warn("sstp: %s error: %s\n", "host-name", ERR_error_string(ERR_get_error(), NULL));
#endif
#ifndef SSL_OP_NO_RENEGOTIATION
diff --git a/accel-pppd/ipv6/dhcpv6.c b/accel-pppd/ipv6/dhcpv6.c
index fc6487b..6daed66 100644
--- a/accel-pppd/ipv6/dhcpv6.c
+++ b/accel-pppd/ipv6/dhcpv6.c
@@ -442,6 +442,8 @@ static void dhcpv6_send_reply(struct dhcpv6_packet *req, struct dhcpv6_pd *pd, i
dhcpv6_packet_print(reply, log_ppp_info2);
}
+ dhcpv6_fill_relay_info(reply);
+
net->sendto(pd->hnd.fd, reply->hdr, reply->endptr - (void *)reply->hdr, 0, (struct sockaddr *)&req->addr, sizeof(req->addr));
dhcpv6_packet_free(reply);
@@ -594,6 +596,8 @@ static void dhcpv6_send_reply2(struct dhcpv6_packet *req, struct dhcpv6_pd *pd,
dhcpv6_packet_print(reply, log_ppp_info2);
}
+ dhcpv6_fill_relay_info(reply);
+
net->sendto(pd->hnd.fd, reply->hdr, reply->endptr - (void *)reply->hdr, 0, (struct sockaddr *)&req->addr, sizeof(req->addr));
out:
@@ -739,6 +743,7 @@ static void dhcpv6_recv_decline(struct dhcpv6_packet *pkt)
// don't answer
}
+
static void dhcpv6_recv_packet(struct dhcpv6_packet *pkt)
{
if (conf_verbose) {
diff --git a/accel-pppd/ipv6/dhcpv6.h b/accel-pppd/ipv6/dhcpv6.h
index 1efbf72..28ea3cf 100644
--- a/accel-pppd/ipv6/dhcpv6.h
+++ b/accel-pppd/ipv6/dhcpv6.h
@@ -34,6 +34,7 @@
#define D6_OPTION_DOMAIN_LIST 24
#define D6_OPTION_IA_PD 25
#define D6_OPTION_IAPREFIX 26
+#define D6_OPTION_IAPREFIX 26
#define D6_SOLICIT 1
#define D6_ADVERTISE 2
@@ -73,6 +74,14 @@ struct dhcpv6_msg_hdr {
uint8_t data[0];
} __packed;
+struct dhcpv6_relay_hdr {
+ uint8_t type;
+ uint8_t hop_cnt;
+ struct in6_addr link_addr;
+ struct in6_addr peer_addr;
+ uint8_t data[0];
+} __packed;
+
struct dhcpv6_duid {
uint16_t type;
union {
@@ -154,6 +163,14 @@ struct dhcpv6_option {
struct dhcpv6_pd;
+struct dhcpv6_relay {
+ struct list_head entry;
+ int hop_cnt;
+ struct in6_addr link_addr;
+ struct in6_addr peer_addr;
+ void *hdr;
+};
+
struct dhcpv6_packet {
struct ap_session *ses;
struct dhcpv6_pd *pd;
@@ -162,6 +179,9 @@ struct dhcpv6_packet {
struct dhcpv6_msg_hdr *hdr;
struct dhcpv6_opt_clientid *clientid;
struct dhcpv6_opt_serverid *serverid;
+
+ struct list_head relay_list;
+
int rapid_commit:1;
struct list_head opt_list;
@@ -174,5 +194,6 @@ void dhcpv6_packet_print(struct dhcpv6_packet *pkt, void (*print)(const char *fm
struct dhcpv6_packet *dhcpv6_packet_alloc_reply(struct dhcpv6_packet *req, int type);
struct dhcpv6_option *dhcpv6_option_alloc(struct dhcpv6_packet *pkt, int code, int len);
struct dhcpv6_option *dhcpv6_nested_option_alloc(struct dhcpv6_packet *pkt, struct dhcpv6_option *opt, int code, int len);
+void dhcpv6_fill_relay_info(struct dhcpv6_packet *pkt);
#endif
diff --git a/accel-pppd/ipv6/dhcpv6_packet.c b/accel-pppd/ipv6/dhcpv6_packet.c
index 664a116..aae260e 100644
--- a/accel-pppd/ipv6/dhcpv6_packet.c
+++ b/accel-pppd/ipv6/dhcpv6_packet.c
@@ -104,9 +104,11 @@ struct dhcpv6_packet *dhcpv6_packet_parse(const void *buf, size_t size)
{
struct dhcpv6_packet *pkt;
struct dhcpv6_opt_hdr *opth;
+ struct dhcpv6_relay *rel;
+ struct dhcpv6_relay_hdr *rhdr;
void *ptr, *endptr;
- pkt = _malloc(sizeof(*pkt));
+ pkt = _malloc(sizeof(*pkt) + size);
if (!pkt) {
log_emerg("out of memory\n");
return NULL;
@@ -114,18 +116,42 @@ struct dhcpv6_packet *dhcpv6_packet_parse(const void *buf, size_t size)
memset(pkt, 0, sizeof(*pkt));
INIT_LIST_HEAD(&pkt->opt_list);
+ INIT_LIST_HEAD(&pkt->relay_list);
- pkt->hdr = _malloc(size);
- if (!pkt->hdr) {
- log_emerg("out of memory\n");
- _free(pkt);
- return NULL;
- }
+ pkt->hdr = (void *)(pkt + 1);
memcpy(pkt->hdr, buf, size);
+ endptr = ((void *)pkt->hdr) + size;
+
+ while (pkt->hdr->type == D6_RELAY_FORW) {
+ rhdr = (struct dhcpv6_relay_hdr *)pkt->hdr;
+ rel = _malloc(sizeof(*rel));
+ rel->hop_cnt = rhdr->hop_cnt;
+ memcpy(&rel->link_addr, &rhdr->link_addr, sizeof(rel->link_addr));
+ memcpy(&rel->peer_addr, &rhdr->peer_addr, sizeof(rel->peer_addr));
+
+ list_add_tail(&rel->entry, &pkt->relay_list);
+
+ ptr = rhdr->data;
+ while (ptr < endptr) {
+ opth = ptr;
+
+ if (ptr + sizeof(*opth) + ntohs(opth->len) > endptr) {
+ log_warn("dhcpv6: invalid packet received\n");
+ dhcpv6_packet_free(pkt);
+ return NULL;
+ }
+
+ if (opth->code == htons(D6_OPTION_RELAY_MSG)) {
+ pkt->hdr = (struct dhcpv6_msg_hdr *)opth->data;
+ endptr = opth->data + sizeof(*opth) + ntohs(opth->len);
+ }
+
+ ptr += sizeof(*opth) + ntohs(opth->len);
+ }
+ }
ptr = pkt->hdr->data;
- endptr = ((void *)pkt->hdr) + size;
while (ptr < endptr) {
opth = ptr;
@@ -199,11 +225,36 @@ struct dhcpv6_option *dhcpv6_nested_option_alloc(struct dhcpv6_packet *pkt, stru
return opt;
}
+void dhcpv6_fill_relay_info(struct dhcpv6_packet *pkt)
+{
+ struct dhcpv6_relay *rel;
+ struct dhcpv6_opt_hdr *opt;
+ struct dhcpv6_relay_hdr *rhdr;
+
+ if (list_empty(&pkt->relay_list))
+ return;
+
+ list_for_each_entry(rel, &pkt->relay_list, entry) {
+ rhdr = (struct dhcpv6_relay_hdr *)rel->hdr;
+ rhdr->type = D6_RELAY_REPL;
+ rhdr->hop_cnt = rel->hop_cnt;
+ memcpy(&rhdr->link_addr, &rel->link_addr, sizeof(rhdr->link_addr));
+ memcpy(&rhdr->peer_addr, &rel->peer_addr, sizeof(rhdr->peer_addr));
+ opt = (struct dhcpv6_opt_hdr *)rhdr->data;
+ opt->code = htons(D6_OPTION_RELAY_MSG);
+ opt->len = (uint8_t *)pkt->endptr - rhdr->data;
+ }
+
+ rel = list_entry(pkt->relay_list.next, typeof(*rel), entry);
+
+ pkt->hdr = (struct dhcpv6_msg_hdr *)rel->hdr;
+}
struct dhcpv6_packet *dhcpv6_packet_alloc_reply(struct dhcpv6_packet *req, int type)
{
- struct dhcpv6_packet *pkt = _malloc(sizeof(*pkt));
+ struct dhcpv6_packet *pkt = _malloc(sizeof(*pkt) + BUF_SIZE);
struct dhcpv6_option *opt;
+ struct dhcpv6_relay *rel;
if (!pkt) {
log_emerg("out of memory\n");
@@ -212,20 +263,23 @@ struct dhcpv6_packet *dhcpv6_packet_alloc_reply(struct dhcpv6_packet *req, int t
memset(pkt, 0, sizeof(*pkt));
INIT_LIST_HEAD(&pkt->opt_list);
+ INIT_LIST_HEAD(&pkt->relay_list);
pkt->ses = req->ses;
- pkt->hdr = _malloc(BUF_SIZE);
- if (!pkt->hdr) {
- log_emerg("out of memory\n");
- _free(pkt);
- return NULL;
+ pkt->hdr = (void *)(pkt + 1);
+
+ while (!list_empty(&req->relay_list)) {
+ rel = list_entry(req->relay_list.next, typeof(*rel), entry);
+ rel->hdr = (void *)pkt->hdr;
+ pkt->hdr = (void *)rel->hdr + sizeof(struct dhcpv6_relay_hdr) + sizeof(struct dhcpv6_opt_hdr);
+ list_move_tail(&rel->entry, &pkt->relay_list);
}
+ pkt->endptr = pkt->hdr->data;
+
pkt->hdr->type = type;
pkt->hdr->trans_id = req->hdr->trans_id;
- pkt->endptr = pkt->hdr->data;
-
opt = dhcpv6_option_alloc(pkt, D6_OPTION_SERVERID, ntohs(req->serverid->hdr.len));
memcpy(opt->hdr, req->serverid, sizeof(struct dhcpv6_opt_hdr) + ntohs(req->serverid->hdr.len));
@@ -247,10 +301,21 @@ static void free_options(struct list_head *opt_list)
}
}
+static void free_relays(struct list_head *list)
+{
+ struct dhcpv6_relay *rel;
+
+ while (!list_empty(list)) {
+ rel = list_entry(list->next, typeof(*rel), entry);
+ list_del(&rel->entry);
+ _free(rel);
+ }
+}
+
void dhcpv6_packet_free(struct dhcpv6_packet *pkt)
{
free_options(&pkt->opt_list);
- _free(pkt->hdr);
+ free_relays(&pkt->relay_list);
_free(pkt);
}
diff --git a/accel-pppd/main.c b/accel-pppd/main.c
index e31a81c..cb7e1cd 100644
--- a/accel-pppd/main.c
+++ b/accel-pppd/main.c
@@ -146,6 +146,7 @@ static void close_all_fd(void)
static void __core_restart(int soft)
{
char exe[PATH_MAX];
+ char exe_buf[PATH_MAX];
pthread_sigmask(SIG_SETMASK, &orig_set, NULL);
@@ -157,7 +158,7 @@ static void __core_restart(int soft)
close_all_fd();
sprintf(exe, "/proc/%u/exe", getpid());
- readlink(exe, exe, PATH_MAX);
+ readlink(exe, exe_buf, PATH_MAX);
while (1) {
execv(exe, argv);
@@ -180,6 +181,7 @@ static void sigsegv(int num)
char cmd[128];
char dump[128];
char exec_file[PATH_MAX];
+ char exec_file_buf[PATH_MAX];
pid_t pid;
FILE *f;
int fd;
@@ -213,7 +215,7 @@ static void sigsegv(int num)
fclose(f);
sprintf(exec_file, "/proc/%s/exe", pid_str);
- readlink(exec_file, exec_file, PATH_MAX);
+ readlink(exec_file, exec_file_buf, PATH_MAX);
execlp("gdb", "gdb", "-x", cmd, exec_file, pid_str, NULL);
perror("exec");
diff --git a/accel-pppd/ppp/ipcp_opt_ipaddr.c b/accel-pppd/ppp/ipcp_opt_ipaddr.c
index 7bac55b..03eb418 100644
--- a/accel-pppd/ppp/ipcp_opt_ipaddr.c
+++ b/accel-pppd/ppp/ipcp_opt_ipaddr.c
@@ -171,9 +171,14 @@ static void load_config(void)
{
const char *opt;
- opt = conf_get_opt("ppp", "check-ip");
- if (opt && atoi(opt) >= 0)
- conf_check_exists = atoi(opt) > 0;
+ opt = conf_get_opt("common", "check-ip");
+ if (opt && atoi(opt) > 0)
+ conf_check_exists = atoi(opt);
+ else {
+ opt = conf_get_opt("ppp", "check-ip");
+ if (opt && atoi(opt) >= 0)
+ conf_check_exists = atoi(opt) > 0;
+ }
}
static void ipaddr_opt_init()
diff --git a/accel-pppd/radius/acct.c b/accel-pppd/radius/acct.c
index b17016d..c0b0190 100644
--- a/accel-pppd/radius/acct.c
+++ b/accel-pppd/radius/acct.c
@@ -487,6 +487,8 @@ int rad_acct_stop(struct radius_pd_t *rpd)
break;
}
+ req->pack->id++;
+
rad_packet_change_val(req->pack, NULL, "Acct-Status-Type", "Stop");
req_set_stat(req, rpd->ses);
req_set_RA(req, req->serv->secret);
diff --git a/accel-pppd/shaper/shaper.c b/accel-pppd/shaper/shaper.c
index 304a129..13f75c0 100644
--- a/accel-pppd/shaper/shaper.c
+++ b/accel-pppd/shaper/shaper.c
@@ -64,6 +64,9 @@ int conf_lq_arg6;
static int temp_down_speed;
static int temp_up_speed;
+static int dflt_down_speed;
+static int dflt_up_speed;
+
static pthread_rwlock_t shaper_lock = PTHREAD_RWLOCK_INITIALIZER;
static LIST_HEAD(shaper_list);
@@ -515,9 +518,7 @@ static void ev_ppp_pre_up(struct ap_session *ses)
up_speed = temp_up_speed;
down_burst = 0;
up_burst = 0;
- } else {
- if (!pd->cur_tr)
- return;
+ } else if (pd->cur_tr){
pd->down_speed = pd->cur_tr->down_speed;
pd->up_speed = pd->cur_tr->up_speed;
down_speed = pd->cur_tr->down_speed;
@@ -525,6 +526,15 @@ static void ev_ppp_pre_up(struct ap_session *ses)
down_burst = pd->cur_tr->down_burst;
up_burst = pd->cur_tr->up_burst;
}
+ else if (dflt_down_speed || dflt_up_speed){
+ pd->down_speed = dflt_down_speed;
+ pd->up_speed = dflt_up_speed;
+ down_speed = dflt_down_speed;
+ up_speed = dflt_up_speed;
+ down_burst = 0;
+ up_burst = 0;
+ }
+ else return;
if (!pd->idx)
pd->idx = alloc_idx(ses->ifindex);
@@ -873,6 +883,22 @@ static struct time_range_t *parse_range(time_t t, const char *val)
return r;
}
+static int parse_dflt_shaper(const char *opt, int *down_speed, int *up_speed)
+{
+ char *endptr;
+
+ *down_speed = strtol(opt, &endptr, 10);
+
+ if (*endptr != '/'){
+ *up_speed = *down_speed;
+ return 0;
+ }
+
+ opt = endptr + 1;
+ *up_speed = strtol(opt, &endptr, 10);
+ return 0;
+}
+
static void load_time_ranges(void)
{
struct conf_sect_t *s = conf_get_section("shaper");
@@ -1101,6 +1127,10 @@ static void load_config(void)
else
conf_fwmark = 0;
+ opt = conf_get_opt("shaper", "rate-limit");
+ if (opt)
+ parse_dflt_shaper(opt, &dflt_down_speed, &dflt_up_speed);
+
triton_context_call(&shaper_ctx, (triton_event_func)load_time_ranges, NULL);
}