ppp: add shellsync

This commit is contained in:
CN_SZTL 2020-03-24 21:25:32 +08:00
parent f74714f616
commit 34ba359c80
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
5 changed files with 362 additions and 8 deletions

View File

@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=ppp
PKG_RELEASE:=2
PKG_RELEASE:=5
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/paulusmack/ppp
@ -38,7 +38,7 @@ endef
define Package/ppp
$(call Package/ppp/Default)
DEPENDS:=+kmod-ppp
DEPENDS:=+kmod-ppp +libpthread +shellsync +kmod-mppe
TITLE:=PPP daemon
VARIANT:=default
endef

View File

@ -74,7 +74,7 @@ ppp_generic_init_config() {
proto_config_add_string pppd_options
proto_config_add_string 'connect:file'
proto_config_add_string 'disconnect:file'
[ -e /proc/sys/net/ipv6 ] && proto_config_add_string ipv6
proto_config_add_string ipv6
proto_config_add_boolean authfail
proto_config_add_int mtu
proto_config_add_string pppname
@ -88,9 +88,7 @@ ppp_generic_setup() {
local config="$1"; shift
local localip
json_get_vars ip6table demand keepalive keepalive_adaptive username password pppd_options pppname unnumbered persist maxfail holdoff peerdns
[ ! -e /proc/sys/net/ipv6 ] && ipv6=0 || json_get_var ipv6 ipv6
json_get_vars ipv6 ip6table demand keepalive keepalive_adaptive username password pppd_options pppname unnumbered persist maxfail holdoff peerdns
if [ "$ipv6" = 0 ]; then
ipv6=""
@ -151,9 +149,9 @@ ppp_generic_setup() {
${connect:+connect "$connect"} \
${disconnect:+disconnect "$disconnect"} \
ip-up-script /lib/netifd/ppp-up \
${ipv6:+ipv6-up-script /lib/netifd/ppp6-up} \
ipv6-up-script /lib/netifd/ppp6-up \
ip-down-script /lib/netifd/ppp-down \
${ipv6:+ipv6-down-script /lib/netifd/ppp-down} \
ipv6-down-script /lib/netifd/ppp-down \
${mtu:+mtu $mtu mru $mtu} \
"$@" $pppd_options
}
@ -233,7 +231,16 @@ proto_pppoe_setup() {
json_get_var padi_attempts padi_attempts
json_get_var padi_timeout padi_timeout
#By 蝈蝈:并发拨号同步的前期准备
syncppp_option=""
[ "$(uci get syncdial.config.enabled)" == "1" ] && {
ppp_if_cnt=$(cat /etc/config/network | grep -c "proto 'pppoe'")
syncppp_option="syncppp $ppp_if_cnt"
shellsync $ppp_if_cnt 10
}
ppp_generic_setup "$config" \
$syncppp_option \
plugin rp-pppoe.so \
${ac:+rp_pppoe_ac "$ac"} \
${service:+rp_pppoe_service "$service"} \

View File

@ -0,0 +1,207 @@
--- a/pppd/chap-new.c
+++ b/pppd/chap-new.c
@@ -37,6 +37,8 @@
#include "chap-new.h"
#include "chap-md5.h"
+#include "syncppp.h"
+
#ifdef CHAPMS
#include "chap_ms.h"
#define MDTYPE_ALL (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT | MDTYPE_MD5)
@@ -492,6 +494,19 @@ chap_respond(struct chap_client_state *c
p[2] = len >> 8;
p[3] = len;
+ if (npppd > 1) {
+ if (syncppp(npppd) < 0) {
+ error("syncppp sync fail");
+ sem_unlink(SEM_COUNT_NAME);
+ sem_unlink(SEM_BLOCK_NAME);
+ } else {
+ info("syncppp sync succeeded");
+ }
+ } else {
+ info("syncppp not active");
+ }
+
+
output(0, response, PPP_HDRLEN + len);
}
--- a/pppd/Makefile.linux
+++ b/pppd/Makefile.linux
@@ -13,16 +13,16 @@ TARGETS = pppd
PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap-new.c md5.c ccp.c \
ecp.c ipxcp.c auth.c options.c sys-linux.c md4.c chap_ms.c \
- demand.c utils.c tty.c eap.c chap-md5.c session.c
+ demand.c utils.c tty.c eap.c chap-md5.c session.c syncppp.c
HEADERS = ccp.h session.h chap-new.h ecp.h fsm.h ipcp.h \
ipxcp.h lcp.h magic.h md5.h patchlevel.h pathnames.h pppd.h \
- upap.h eap.h
+ upap.h eap.h syncppp.h
MANPAGES = pppd.8
PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap-new.o md5.o ccp.o \
ecp.o auth.o options.o demand.o utils.o sys-linux.o ipxcp.o tty.o \
- eap.o chap-md5.o session.o
+ eap.o chap-md5.o session.o syncppp.o
#
# include dependencies if present
@@ -33,7 +33,7 @@ endif
# CC = gcc
#
COPTS = -O2 -pipe -Wall -g
-LIBS =
+LIBS = -lpthread
# Uncomment the next line to include support for Microsoft's
# MS-CHAP authentication protocol. Also, edit plugins/radius/Makefile.linux.
--- a/pppd/options.c
+++ b/pppd/options.c
@@ -128,6 +128,7 @@ bool dump_options; /* print out option
bool dryrun; /* print out option values and exit */
char *domain; /* domain name set by domain option */
int child_wait = 5; /* # seconds to wait for children at exit */
+int npppd = 0; /* synchronize between multiple pppd */
struct userenv *userenv_list; /* user environment variables */
int dfl_route_metric = -1; /* metric of the default route to set over the PPP link */
@@ -342,6 +343,10 @@ option_t general_options[] = {
"Set pathname of ipv6-down script",
OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
+ { "syncppp", o_int, &npppd,
+ "sync among multiple pppd when sending chap/pap respond", OPT_PRIO },
+
+
#ifdef HAVE_MULTILINK
{ "multilink", o_bool, &multilink,
"Enable multilink operation", OPT_PRIO | 1 },
--- a/pppd/pppd.h
+++ b/pppd/pppd.h
@@ -343,6 +343,7 @@ extern char *bundle_name; /* bundle name
extern bool dump_options; /* print out option values */
extern bool dryrun; /* check everything, print options, exit */
extern int child_wait; /* # seconds to wait for children at end */
+extern int npppd; /* synchronize between multiple pppd */
#ifdef MAXOCTETS
extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */
--- /dev/null
+++ b/pppd/syncppp.c
@@ -0,0 +1,75 @@
+#include<stdio.h>
+#include<semaphore.h>
+#include<fcntl.h>
+#include<stdlib.h>
+#include<time.h>
+#include<errno.h>
+#include "pppd.h"
+#include "syncppp.h"
+
+int syncppp(int nproc)
+{
+ int flags;
+ int value;
+ sem_t *block;
+ sem_t *count;
+ struct timespec ts;
+
+ if (nproc <= 1) {
+ error("syncppp: number of pppd should be larger than 1");
+ return -1;
+ }
+
+ if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
+ error("clock_gettime error");
+ return -1;
+ }
+ ts.tv_sec += SYNCPPP_TIMEOUT;
+
+
+ flags = O_RDWR | O_CREAT;
+ block = sem_open(SEM_BLOCK_NAME, flags, 0644, 0);
+ count = sem_open(SEM_COUNT_NAME, flags, 0644, 0);
+ if (block == SEM_FAILED || count == SEM_FAILED) {
+ error("syncppp: sem_open failed");
+ return -1;
+ }
+
+ if (sem_post(count) < 0) {
+ error("syncppp: sem_post failed");
+ return -1;
+ }
+ if (sem_getvalue(count, &value) < 0) {
+ error("syncppp: sem_getvalue failed");
+ return -1;
+ }
+ info("%d pppd have arrived, waiting for the left %d", value, nproc-value);
+ if (value >= nproc) {
+ while (nproc-1 > 0) {
+ if (sem_post(block) < 0) {
+ error("syncppp: sem_post failed");
+ return -1;
+ }
+ nproc--;
+ }
+ } else {
+ if (sem_timedwait(block, &ts) < 0) {
+ if (errno == ETIMEDOUT) {
+ error("syncppp: sem_timewait time out");
+ } else {
+ error("syncppp: sem_timewait error");
+ }
+ return -1;
+ }
+
+ }
+
+ sem_close(count);
+ sem_close(block);
+
+ sem_unlink(SEM_COUNT_NAME);
+ sem_unlink(SEM_BLOCK_NAME);
+
+ return 0;
+}
+
--- /dev/null
+++ b/pppd/syncppp.h
@@ -0,0 +1,3 @@
+#define SEM_BLOCK_NAME "block"
+#define SEM_COUNT_NAME "count"
+#define SYNCPPP_TIMEOUT 5
--- a/pppd/upap.c
+++ b/pppd/upap.c
@@ -52,6 +52,7 @@
#include "pppd.h"
#include "upap.h"
+#include "syncppp.h"
static bool hide_password = 1;
@@ -567,6 +568,18 @@ upap_sauthreq(u)
PUTCHAR(u->us_passwdlen, outp);
BCOPY(u->us_passwd, outp, u->us_passwdlen);
+ if (npppd > 1) {
+ if (syncppp(npppd) < 0) {
+ error("syncppp sync fail");
+ sem_unlink(SEM_COUNT_NAME);
+ sem_unlink(SEM_BLOCK_NAME);
+ } else {
+ info("syncppp sync succeeded");
+ }
+ } else {
+ info("syncppp not active");
+ }
+
output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
TIMEOUT(upap_timeout, u, u->us_timeouttime);

View File

@ -0,0 +1,34 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=shellsync
PKG_VERSION:=0.2
PKG_RELEASE:=2
include $(INCLUDE_DIR)/package.mk
define Package/shellsync
CATEGORY:=Utilities
TITLE:=shellsync
DEPENDS:=+libpthread +kmod-macvlan
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Package/shellsync/description
A tool to sync different shell scripts.Based on syncppp patch by morfast.
endef
define Build/Compile
$(TARGET_CROSS)gcc -pthread -o $(PKG_BUILD_DIR)/shellsync $(PKG_BUILD_DIR)/shellsync.c
endef
define Package/shellsync/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/shellsync $(1)/usr/bin
endef
$(eval $(call BuildPackage,shellsync))

View File

@ -0,0 +1,106 @@
/*************************************************************************
> File Name: shellsync.c
> Author: GuoGuo
> Mail: gch981213@gmail.com
> Created Time: 20141106 191530
************************************************************************/
#include<stdio.h>
#include<semaphore.h>
#include<fcntl.h>
#include<stdlib.h>
#include<time.h>
#include<errno.h>
#define SEM_BLOCK_NAME "SYNCSHELL_block"
#define SEM_COUNT_NAME "SYNCSHELL_count"
int wait_timeout;
int sync_wait(int nproc)
{
int flags;
int value;
sem_t *block;
sem_t *count;
struct timespec ts;
if (nproc <= 1) {
printf("sync_wait: number of processes should be larger than 1\n");
return -1;
}
if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
printf("clock_gettime error\n");
return -1;
}
ts.tv_sec += wait_timeout;
flags = O_RDWR | O_CREAT;
block = sem_open(SEM_BLOCK_NAME, flags, 0644, 0);
count = sem_open(SEM_COUNT_NAME, flags, 0644, 0);
if (block == SEM_FAILED || count == SEM_FAILED) {
printf("sync_wait: sem_open failed\n");
return -1;
}
if (sem_post(count) < 0) {
printf("sync_wait: sem_post failed\n");
return -1;
}
if (sem_getvalue(count, &value) < 0) {
printf("sync_wait: sem_getvalue failed\n");
return -1;
}
printf("%d processes have arrived, waiting for the left %d\n", value, nproc-value);
if (value >= nproc) {
while (nproc-1 > 0) {
if (sem_post(block) < 0) {
printf("sync_wait: sem_post failed\n");
return -1;
}
nproc--;
}
} else {
if (sem_timedwait(block, &ts) < 0) {
if (errno == ETIMEDOUT) {
printf("sync_wait: sem_timewait time out\n");
} else {
printf("sync_wait: sem_timewait error\n");
}
return -1;
}
}
sem_close(count);
sem_close(block);
sem_unlink(SEM_COUNT_NAME);
sem_unlink(SEM_BLOCK_NAME);
return 0;
}
int main(int argc,char *argv[])
{
if(argc!=3)
{
printf("Usage: shellsync <process num> <wait_timeout>\n");
}
else
{
int proc_num;
sscanf(argv[1],"%d",&proc_num);
sscanf(argv[2],"%d",&wait_timeout);
if(sync_wait(proc_num)<0)
{
printf("Processes sync failed.\n");
sem_unlink(SEM_COUNT_NAME);
sem_unlink(SEM_BLOCK_NAME);
return 1;
}
else
{
printf("Processes sync succeed.\n");
return 0;
}
}
}