diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | accel-pppd/accel-ppp.conf | 4 | ||||
-rw-r--r-- | accel-pppd/accel-ppp.conf.5 | 12 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.c | 28 | ||||
-rw-r--r-- | accel-pppd/ctrl/sstp/sstp.c | 101 | ||||
-rw-r--r-- | accel-pppd/ipv6/dhcpv6.c | 5 | ||||
-rw-r--r-- | accel-pppd/ipv6/dhcpv6.h | 21 | ||||
-rw-r--r-- | accel-pppd/ipv6/dhcpv6_packet.c | 99 | ||||
-rw-r--r-- | accel-pppd/main.c | 6 | ||||
-rw-r--r-- | accel-pppd/ppp/ipcp_opt_ipaddr.c | 11 | ||||
-rw-r--r-- | accel-pppd/radius/acct.c | 2 | ||||
-rw-r--r-- | accel-pppd/shaper/shaper.c | 36 | ||||
-rw-r--r-- | cmake/cpack.cmake | 4 |
13 files changed, 277 insertions, 54 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 67e138a..fe8ac94 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,7 +48,7 @@ IF (EXISTS ${CMAKE_HOME_DIRECTORY}/.git AND NOT IGNORE_GIT) ) STRING(STRIP ${ACCEL_PPP_VERSION} ACCEL_PPP_VERSION) ELSE (EXISTS ${CMAKE_HOME_DIRECTORY}/.git AND NOT IGNORE_GIT) - SET (ACCEL_PPP_VERSION 1.11.0) + SET (ACCEL_PPP_VERSION 1.12.0) ENDIF (EXISTS ${CMAKE_HOME_DIRECTORY}/.git AND NOT IGNORE_GIT) ADD_DEFINITIONS(-DACCEL_PPP_VERSION="${ACCEL_PPP_VERSION}") 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); } diff --git a/cmake/cpack.cmake b/cmake/cpack.cmake index 8f432a1..d597074 100644 --- a/cmake/cpack.cmake +++ b/cmake/cpack.cmake @@ -1,8 +1,8 @@ INCLUDE(InstallRequiredSystemLibraries) SET(CPACK_PACKAGE_VERSION_MAJOR "1") -SET(CPACK_PACKAGE_VERSION_MINOR "11") -SET(CPACK_PACKAGE_VERSION_PATCH "99") +SET(CPACK_PACKAGE_VERSION_MINOR "12") +SET(CPACK_PACKAGE_VERSION_PATCH "0") SET(CPACK_PACKAGE_NAME "accel-ppp") SET(CPACK_PACKAGE_CONTACT "Dmitry Kozlov <xeb@mail.ru>") |