[Olsr-dev] [PATCH RFC v1 2/4] smart gateway: hook up SmartGatewaySpeedFile{, Period} parameters

Hans-Christoph Steiner (spam-protected)
Thu May 10 18:42:32 CEST 2012


This makes the core depend on regex.h which is not guaranteed on all platforms.  Windows and Android (< 2.3) do not natively provide regex support.

.hc


On May 10, 2012, at 11:56 AM, Ferry Huberts wrote:

> From: Ferry Huberts <(spam-protected)>
> 
> Signed-off-by: Ferry Huberts <(spam-protected)>
> ---
> make/Makefile.win32    |    2 +-
> src/gateway.c          |   52 ++++++++++++-
> src/gatewaySpeedFile.c |  201 ++++++++++++++++++++++++++++++++++++++++++++++++
> src/gatewaySpeedFile.h |   13 +++
> 4 files changed, 266 insertions(+), 2 deletions(-)
> create mode 100644 src/gatewaySpeedFile.c
> create mode 100644 src/gatewaySpeedFile.h
> 
> diff --git a/make/Makefile.win32 b/make/Makefile.win32
> index cf4a4a2..3693ef4 100644
> --- a/make/Makefile.win32
> +++ b/make/Makefile.win32
> @@ -9,7 +9,7 @@ SRCS +=		$(wildcard src/win32/*.c)
> HDRS +=		$(wildcard src/win32/*.h)
> 
> CPPFLAGS +=	-DWIN32 -D_WIN32_WINNT=0x0600
> -LIBS +=		-mno-cygwin -lws2_32 -liphlpapi
> +LIBS +=		-mno-cygwin -lws2_32 -liphlpapi -lregex
> CPPFLAGS += 	-I$(TOPDIR)/src/win32
> CFLAGS +=	-mno-cygwin
> 
> diff --git a/src/gateway.c b/src/gateway.c
> index 048a7cb..84d88b3 100644
> --- a/src/gateway.c
> +++ b/src/gateway.c
> @@ -19,6 +19,7 @@
> #include "log.h"
> #include "gateway_default_handler.h"
> #include "gateway.h"
> +#include "gatewaySpeedFile.h"
> 
> #include <assert.h>
> #include <net/if.h>
> @@ -87,6 +88,14 @@ static void smartgw_tunnel_monitor (int if_index __attribute__ ((unused)),
> }
> 
> /**
> + * Timer callback that reads the smart gateway speed file
> + */
> +static void smartgw_read_speed_file(void *context __attribute__ ((unused))) {
> +	readGatewaySpeedFile(olsr_cnf->smart_gw_speed_file);
> +	return;
> +}
> +
> +/**
>  * Initialize gateway system
>  */
> int
> @@ -107,6 +116,10 @@ olsr_init_gateways(void) {
>     return 1;
>   }
> 
> +  if (!startGatewaySpeedFile()) {
> +	  return 1;
> +  }
> +
>   olsr_add_ifchange_handler(smartgw_tunnel_monitor);
> 
>   /*
> @@ -140,10 +153,26 @@ void refresh_smartgw_netmask(void) {
>   }
> }
> 
> +/** The timer cookie, used to trace back the originator in debug */
> +static struct olsr_cookie_info *smartgw_speed_file_timer_cookie = NULL;
> +
> +/** The timer */
> +static struct timer_entry * smartgw_speed_file_timer = NULL;
> +
> /**
>  * Cleanup gateway tunnel system
>  */
> void olsr_cleanup_gateways(void) {
> +  if (smartgw_speed_file_timer != NULL) {
> +	olsr_stop_timer(smartgw_speed_file_timer);
> +	smartgw_speed_file_timer = NULL;
> +  }
> +  if (smartgw_speed_file_timer_cookie != NULL) {
> +	olsr_free_cookie(smartgw_speed_file_timer_cookie);
> +	smartgw_speed_file_timer_cookie = NULL;
> +  }
> +  stopGatewaySpeedFile();
> +
>   if (current_ipv4_gw) {
>     olsr_os_del_ipip_tunnel(v4gw_tunnel);
>   }
> @@ -161,7 +190,28 @@ void olsr_cleanup_gateways(void) {
>  */
> void
> olsr_trigger_inetgw_startup(void) {
> -  gw_handler->handle_startup();
> +	if (olsr_cnf->smart_gw_speed_file) {
> +		smartgw_read_speed_file(NULL);
> +
> +		if (smartgw_speed_file_timer_cookie == NULL) {
> +			smartgw_speed_file_timer_cookie = olsr_alloc_cookie("smartgw speed file", OLSR_COOKIE_TYPE_TIMER);
> +			if (smartgw_speed_file_timer_cookie == NULL) {
> +				olsr_syslog(OLSR_LOG_ERR,
> +						"Could not allocate smart gateway speed file cookie, will not read the file.\n");
> +				return;
> +			}
> +		}
> +		if (smartgw_speed_file_timer == NULL) {
> +			smartgw_speed_file_timer = olsr_start_timer(olsr_cnf->smart_gw_speed_file_period, 0, OLSR_TIMER_PERIODIC,
> +					&smartgw_read_speed_file, NULL, smartgw_speed_file_timer_cookie);
> +			if (smartgw_speed_file_timer == NULL) {
> +				olsr_syslog(OLSR_LOG_ERR, "Could not start smart gateway speed file timer, will not read the file.\n");
> +				return;
> +			}
> +		}
> +	}
> +
> +	gw_handler->handle_startup();
> }
> 
> /**
> diff --git a/src/gatewaySpeedFile.c b/src/gatewaySpeedFile.c
> new file mode 100644
> index 0000000..72cfbf9
> --- /dev/null
> +++ b/src/gatewaySpeedFile.c
> @@ -0,0 +1,201 @@
> +#include "gatewaySpeedFile.h"
> +
> +#include "log.h"
> +#include <regex.h>
> +#include <sys/stat.h>
> +
> +#define LINE_LENGTH 256
> +
> +static const char * regexCommentString = "^([[:space:]]*|[[:space:]#]+.*)$";
> +static const char * regexNameValueString =
> +		"^[[:space:]]*([^[:space:]]+)[[:space:]]*=[[:space:]]*([[:digit:]]+)[[:space:]]*$";
> +static const size_t regexNameValuematchCount = 3;
> +
> +static regex_t regexComment;
> +static regex_t regexNameValue;
> +static bool started = false;
> +
> +typedef struct _CachedStat {
> +#ifdef linux
> +	struct timespec st_mtim; /* Time of last modification. */
> +#else
> +	time_t st_mtime; /* Time of last modification. */
> +#endif
> +} CachedStat;
> +
> +static CachedStat cachedStat;
> +
> +/**
> + Read an unsigned long number from a value string
> +
> + @param valueName
> + the name of the value
> + @param value
> + the string to convert to a number
> + @param valueNumber
> + a pointer to the location where to store the number upon successful conversion
> +
> + @return
> + - true on success
> + - false otherwise
> + */
> +static bool readUL(const char * valueName, const char * value, unsigned long * valueNumber) {
> +	char * endPtr = NULL;
> +	unsigned long valueNew;
> +
> +	errno = 0;
> +	valueNew = strtoul(value, &endPtr, 10);
> +
> +	if (!((endPtr != value) && (*value != '\0') && (*endPtr == '\0'))) {
> +		/* invalid conversion */
> +		olsr_syslog(OLSR_LOG_ERR, "Configured %s (%s) could not be converted to a number: %s\n", valueName, value,
> +				strerror(errno));
> +		return false;
> +	}
> +
> +	*valueNumber = valueNew;
> +
> +	return true;
> +}
> +
> +bool startGatewaySpeedFile(void) {
> +	if (started) {
> +		return true;
> +	}
> +
> +	if (regcomp(&regexComment, regexCommentString, REG_EXTENDED)) {
> +		olsr_printf(0, "Could not compile regex \"%s\"\n", regexCommentString);
> +		return false;
> +	}
> +
> +	if (regcomp(&regexNameValue, regexNameValueString, REG_EXTENDED)) {
> +		olsr_printf(0, "Could not compile regex \"%s\"\n", regexNameValueString);
> +		return false;
> +	}
> +
> +#ifdef linux
> +	cachedStat.st_mtim.tv_sec = -1;
> +	cachedStat.st_mtim.tv_nsec = -1;
> +#else
> +	cachedStat.st_mtime = -1;
> +#endif
> +
> +	started = true;
> +	return true;
> +}
> +
> +void stopGatewaySpeedFile(void) {
> +	if (started) {
> +		regfree(&regexNameValue);
> +		regfree(&regexComment);
> +		started = false;
> +	}
> +}
> +
> +static bool regexMatch(regex_t * regex, char * line, size_t nmatch, regmatch_t pmatch[]) {
> +	int result = regexec(regex, line, nmatch, pmatch, 0);
> +	if (!result) {
> +		return true;
> +	}
> +
> +	if (result == REG_NOMATCH) {
> +		return false;
> +	}
> +
> +	{
> +		char msgbuf[256];
> +		regerror(result, regex, msgbuf, sizeof(msgbuf));
> +		olsr_syslog(OLSR_LOG_ERR, "Regex match failed: %s\n", msgbuf);
> +	}
> +
> +	return false;
> +}
> +
> +static char line[LINE_LENGTH];
> +
> +void readGatewaySpeedFile(char * fileName) {
> +	struct stat statBuf;
> +	FILE * fd = NULL;
> +	unsigned int lineNumber = 0;
> +	char * name = NULL;
> +	char * value = NULL;
> +	unsigned long uplink = DEF_UPLINK_SPEED;
> +	unsigned long downlink = DEF_DOWNLINK_SPEED;
> +	bool uplinkSet = false;
> +	bool downlinkSet = false;
> +
> +	if (stat(fileName, &statBuf)) {
> +		/* could not access the file */
> +		goto out;
> +	}
> +
> +#ifdef linux
> +	if (!memcmp(&cachedStat.st_mtim, &statBuf.st_mtim, sizeof(cachedStat.st_mtim))) {
> +#else
> +	if (!memcmp(&cachedStat.st_mtime, &statBuf.st_mtime, sizeof(cachedStat.st_mtime))) {
> +#endif
> +		/* file did not change since last read */
> +		goto out;
> +	}
> +
> +	fd = fopen(fileName, "r");
> +	if (!fd) {
> +		goto out;
> +	}
> +
> +#ifdef linux
> +	memcpy(&cachedStat.st_mtim, &statBuf.st_mtim, sizeof(cachedStat.st_mtim));
> +#else
> +	memcpy(&cachedStat.st_mtime, &statBuf.st_mtime, sizeof(cachedStat.st_mtime));
> +#endif
> +
> +	while (fgets(line, LINE_LENGTH, fd)) {
> +		regmatch_t pmatch[regexNameValuematchCount];
> +
> +		lineNumber++;
> +
> +		if (regexMatch(&regexComment, line, 0, NULL)) {
> +			continue;
> +		}
> +
> +		if (!regexMatch(&regexNameValue, line, regexNameValuematchCount, pmatch)) {
> +			olsr_syslog(OLSR_LOG_ERR, "Gateway speed file \"%s\", line %d uses invalid syntax: %s\n", fileName, lineNumber,
> +					line);
> +			goto out;
> +		}
> +
> +		/* copy name/value */
> +		name = &line[pmatch[1].rm_so];
> +		line[pmatch[1].rm_eo] = '\0';
> +		value = &line[pmatch[2].rm_so];
> +		line[pmatch[2].rm_eo] = '\0';
> +
> +		if (!strncasecmp(GATEWAY_SPEED_UPLINK, name, sizeof(line))) {
> +			if (!readUL(GATEWAY_SPEED_UPLINK, value, &uplink)) {
> +				goto out;
> +			}
> +			uplinkSet = true;
> +		} else if (!strncasecmp(GATEWAY_SPEED_DOWNLINK, name, sizeof(line))) {
> +			if (!readUL(GATEWAY_SPEED_DOWNLINK, value, &downlink)) {
> +				goto out;
> +			}
> +			downlinkSet = true;
> +		} else {
> +			olsr_syslog(OLSR_LOG_ERR, "Gateway speed file \"%s\", line %d uses an invalid option \"%s\","
> +					" valid options are [%s|%s]\n", fileName, lineNumber, name, GATEWAY_SPEED_UPLINK,
> +					GATEWAY_SPEED_DOWNLINK);
> +			goto out;
> +		}
> +	}
> +
> +	fclose(fd);
> +
> +	if (uplinkSet) {
> +		olsr_cnf->smart_gw_uplink = uplink;
> +	}
> +	if (downlinkSet) {
> +		olsr_cnf->smart_gw_downlink = downlink;
> +	}
> +
> +	out: return;
> +}
> diff --git a/src/gatewaySpeedFile.h b/src/gatewaySpeedFile.h
> new file mode 100644
> index 0000000..e50f607
> --- /dev/null
> +++ b/src/gatewaySpeedFile.h
> @@ -0,0 +1,13 @@
> +#ifndef GATEWAYSPEEDFILE_H
> +#define GATEWAYSPEEDFILE_H
> +
> +#include "olsr.h"
> +
> +#define GATEWAY_SPEED_UPLINK   "upstream"
> +#define GATEWAY_SPEED_DOWNLINK "downstream"
> +
> +bool startGatewaySpeedFile(void);
> +void stopGatewaySpeedFile(void);
> +void readGatewaySpeedFile(char * fileName);
> +
> +#endif /* GATEWAYSPEEDFILE_H */
> -- 
> 1.7.7.6
> 
> 
> -- 
> Olsr-dev mailing list
> (spam-protected)
> https://lists.olsr.org/mailman/listinfo/olsr-dev





More information about the Olsr-dev mailing list