|
@@ -1,204 +0,0 @@
|
|
|
---- 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)
|
|
|
-@@ -523,6 +525,18 @@ chap_respond(struct chap_client_state *cs, int id,
|
|
|
- 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
|
|
|
-@@ -17,16 +17,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
|
|
|
-@@ -34,7 +34,7 @@ ifeq (.depend,$(wildcard .depend))
|
|
|
- include .depend
|
|
|
- endif
|
|
|
-
|
|
|
--LIBS = -lrt
|
|
|
-+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
|
|
|
-@@ -127,6 +127,7 @@ bool dump_options; /* print out option values */
|
|
|
- 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 */
|
|
|
-
|
|
|
-@@ -323,6 +324,9 @@ option_t general_options[] = {
|
|
|
- "Unset user environment variable",
|
|
|
- OPT_A2PRINTER | OPT_NOPRINT, (void *)user_unsetprint },
|
|
|
-
|
|
|
-+ { "syncppp", o_int, &npppd,
|
|
|
-+ "sync among multiple pppd when sending chap/pap respond", OPT_PRIO },
|
|
|
-+
|
|
|
- { "defaultroute-metric", o_int, &dfl_route_metric,
|
|
|
- "Metric to use for the default route (Linux only; -1 for default behavior)",
|
|
|
- OPT_PRIV|OPT_LLIMIT|OPT_INITONLY, NULL, 0, -1 },
|
|
|
---- a/pppd/pppd.h
|
|
|
-+++ b/pppd/pppd.h
|
|
|
-@@ -335,6 +335,7 @@ extern char *bundle_name; /* bundle name for multilink */
|
|
|
- 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 USE_EAPTLS
|
|
|
- extern char *crl_dir;
|
|
|
---- /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
|
|
|
-@@ -50,6 +50,7 @@
|
|
|
- #include "pppd.h"
|
|
|
- #include "upap.h"
|
|
|
-
|
|
|
-+#include "syncppp.h"
|
|
|
-
|
|
|
- static bool hide_password = 1;
|
|
|
-
|
|
|
-@@ -540,6 +541,18 @@ upap_sauthreq(upap_state *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);
|