Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Schedule support for trickle #11

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Makefile.am
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
include $(top_srcdir)/Makefile.am.inc

TRICKLEOVERLOADFILES = @LTLIBOBJS@ trickle-overload.lo bwstat.lo trickledu.lo \
atomicio.lo xdr.lo
atomicio.lo xdr.lo schedule.lo
trickle-overload.so: $(TRICKLEOVERLOADFILES)
$(LIBTOOL) --mode=link $(CC) $(CFLAGS) -o [email protected] \
-rpath $(libdir)/trickle $(TRICKLEOVERLOADFILES) $(LIBS) \
Expand All @@ -22,7 +22,7 @@ trickle_SOURCES = trickle.c util.c getopt.c
trickle_LDADD = @ERRO@ $(LIBOBJS)

trickled_SOURCES = trickled.c atomicio.c print.c bwstat.c client.c conf.c \
util.c cleanup.c getopt.c xdr.c
util.c cleanup.c getopt.c xdr.c schedule.c
trickled_LDADD = @EVENTLIB@ $(LIBOBJS)

tricklectl_SOURCES = tricklectl.c trickledu.c atomicio.c xdr.c
Expand All @@ -33,7 +33,7 @@ AM_CFLAGS = -Wall -Icompat @EVENTINC@
overloaddir = $(libdir)
overload_DATA = libtrickle.so

libtrickle.so: trickle-overload.c atomicio.c
libtrickle.so: trickle-overload.c atomicio.c schedule.c
$(overload_DATA):

CLEANFILES = *.so
Expand All @@ -42,6 +42,6 @@ EXTRA_DIST = LICENSE README strlcat.c strlcpy.c err.c Makefile.am.inc \
compat/sys/queue.h compat/sys/tree.h trickle.1 trickled.8 \
trickled.conf.5 trickle-overload.c trickledu.c cleanup.h \
conf.h message.h trickle.h util.h bwstat.h client.h \
print.h trickledu.h xdr.h
print.h trickledu.h xdr.h schedule.h

ACLOCAL_AMFLAGS = -I m4
134 changes: 134 additions & 0 deletions schedule.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* schedule.c
*
* Copyright (c) 2009-2015 Matthew Blythe <[email protected]>
* All rights reserved.
*
*/

#include <sys/types.h>

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */

#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif /* HAVE_SYS_TIME_H */
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif /* HAVE_STDINT_H */
#if defined(HAVE_TIME_H) && defined(TIME_WITH_SYS_TIME)
#include <time.h>
#endif /* defined(HAVE_TIME_H) && defined(TIME_WITH_SYS_TIME) */
#include <stdlib.h>

#include "trickle.h"
#include "schedule.h"

void
schedString(char* sched, uint* bwList, const char* updown, print_func print)
{
int i,j;
int day[8];
char* place=NULL;
uint defaultBw = atoi(sched)*1024;
print(1,"Default %s Bandwidth: %u bps",updown,defaultBw);
for(i=0; i<(7*24*DIVS_PER_HOUR); i++){
bwList[i] = defaultBw;
}
while(1){
for(i=0;i<7;i++)
day[i]=0;
day[7]=1;
while(sched[0]!='\0' && sched[0]!=':')
sched++;
if(sched[0]=='\0')
return;
sched++;
while(place != sched){
place = sched;
if(sched[0]=='S' && sched[1]=='u'){
day[0]=1;
day[7]=0;
sched += 2;
}
if(sched[0]=='M'){
day[1]=1;
day[7]=0;
sched++;
}
if(sched[0]=='T'){
day[2]=1;
day[7]=0;
sched++;
}
if(sched[0]=='W'){
day[3]=1;
day[7]=0;
sched++;
}
if(sched[0]=='T' && sched[1]=='h'){
day[4]=1;
day[7]=0;
sched += 2;
}
if(sched[0]=='F'){
day[5]=1;
day[7]=0;
sched++;
}
if(sched[0]=='S' && sched[1]=='a'){
day[6]=1;
day[7]=0;
sched += 2;
}
}
uint time1,hr1,div1,time2,hr2,div2,bw;
time1 = atoi(sched);
hr1 = (time1/100)%24;
div1 = ((time1%100)/(60/DIVS_PER_HOUR))%DIVS_PER_HOUR;
while(sched[0]!='\0' && sched[0]!=',')
sched++;
if(sched[0]=='\0')
return;
sched++;
time2 = atoi(sched);
hr2 = (time2/100)%24;
div2 = ((time2%100)/(60/DIVS_PER_HOUR))%DIVS_PER_HOUR;
while(sched[0]!='\0' && sched[0]!=',')
sched++;
if(sched[0]=='\0')
return;
sched++;
bw = atoi(sched);
bw *= 1024;
for(i=0; i<7; i++){
if(day[i]||day[7]){
print(1,"changing %s bandwidth on day %u, between %u:%02u and %u:%02u to %u bps",
updown, i, hr1, div1*(60/DIVS_PER_HOUR), hr2, div2*(60/DIVS_PER_HOUR), bw);
for(j = i*(24*DIVS_PER_HOUR) + hr1*DIVS_PER_HOUR + div1;
j < i*(24*DIVS_PER_HOUR) + hr2*DIVS_PER_HOUR + div2; j++){
bwList[j] = bw;
}
}
}
}
}

uint
getSchedIndex()
{
time_t rawtime;
struct tm * timeinfo;
uint index;

time ( &rawtime );
timeinfo = localtime ( &rawtime );
index = (timeinfo->tm_wday*24*DIVS_PER_HOUR)
+ (timeinfo->tm_hour*DIVS_PER_HOUR)
+ (timeinfo->tm_min/(60/DIVS_PER_HOUR));

return index;
}

20 changes: 20 additions & 0 deletions schedule.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* trickle-overload.c
*
* Copyright (c) 2002, 2003 Marius Aamodt Eriksen <[email protected]>
* All rights reserved.
*
* $Id: trickle-overload.c,v 1.38 2004/02/13 06:11:21 marius Exp $
*/

#ifndef SCHEDULE_H
#define SCHEDULE_H

uint getSchedIndex ();
typedef void (*print_func) (int, const char *, ...);
void schedString (char* sched,
uint* bwList,
const char* updown,
print_func print);

#endif /* !SCHEDULE_H */
10 changes: 6 additions & 4 deletions trickle-overload.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include "message.h"
#include "util.h"
#include "trickledu.h"
#include "schedule.h"

#ifndef INFTIM
#define INFTIM -1
Expand Down Expand Up @@ -101,7 +102,7 @@ TAILQ_HEAD(_pollfdhead, _pollfd);
static TAILQ_HEAD(sockdeschead, sockdesc) sdhead;
static uint32_t winsz;
static int verbose;
static uint lim[2];
static uint lim[2][7*24*DIVS_PER_HOUR];//7 days in week * 24 hours in day * divs in hour
static char *argv0;
static double tsmooth;
static uint lsmooth/* , latency */;
Expand Down Expand Up @@ -283,11 +284,11 @@ trickle_init(void)
*/

winsz = atoi(winszstr) * 1024;
lim[TRICKLE_RECV] = atoi(recvlimstr) * 1024;
lim[TRICKLE_SEND] = atoi(sendlimstr) * 1024;
/* latency = atoi(latencystr);*/
verbose = atoi(verbosestr);
// verbose = -1;
schedString(recvlimstr,lim[TRICKLE_RECV],"download",safe_printv);
schedString(sendlimstr,lim[TRICKLE_SEND],"upload",safe_printv);
if ((tsmooth = strtod(tsmoothstr, (char **)NULL)) <= 0.0)
errx(1, "[trickle] Invalid time smoothing parameter");
lsmooth = atoi(lsmoothstr) * 1024;
Expand Down Expand Up @@ -1145,7 +1146,8 @@ static struct timeval *
getdelay(struct sockdesc *sd, ssize_t *len, short which)
{
struct timeval *xtv;
uint xlim = lim[which];

uint xlim = lim[which][getSchedIndex()];

/* XXX check this. */
if (*len < 0)
Expand Down
79 changes: 73 additions & 6 deletions trickle.1
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
.Op Fl v
.Op Fl V
.Op Fl s
.Op Fl d Ar rate
.Op Fl u Ar rate
.Op Fl d Ar rate\fR[:\fIschedule\fR]
.Op Fl u Ar rate\fR[:\fIschedule\fR]
.Op Fl w Ar length
.Op Fl t Ar time
.Op Fl l Ar length
Expand Down Expand Up @@ -49,14 +49,18 @@ Prints version.
.It Fl s
Runs trickle in standalone mode, independent of
.Xr trickled 8 .
.It Fl d Ar rate
.It Fl d Ar rate\fR[:\fIschedule\fR]
Limit the download bandwidth consumption to
.Ar rate
KB/s.
.It Fl u Ar rate
KB/s. Optionally, set a
.Ar schedule
to follow.
.It Fl u Ar rate\fR[:\fIschedule\fR]
Limit the upload bandwidth consumption to
.Ar rate
KB/s.
KB/s. Optionally, set a
.Ar schedule
to follow.
.It Fl w Ar length
Set peak detection window size to
.Ar length
Expand Down Expand Up @@ -94,13 +98,76 @@ to communicate with
By default,
.Ar /tmp/.trickled.sock
is used.
.El
.Ss "Schedules"
Both the
.Ar -u
and
.Ar -d
flags accept one or more optional schedules, specified in the following form:
.Pp
:[\fIdays_of_week\fR][\fIstart_time\fR],[\fIend_time\fR],[\fIrate\fR]
.Pp
.Ar days_of_week
may be any of
.Ar Su M T W Th F Sa
in any order. If no day is specified, the schedule will apply for all days.
.Pp
.Ar start_time
is the 3-or-4-digit 24-hour local time to begin the new bandwidth schedule.
For example,
.Ar 1234
would mean 12:34 PM.
.Ar 123
would mean 1:23 AM.
.Ar 2345
would mean 11:45 PM.
.Pp
.Ar end_time
is the 3-or-4-digit 24-hour local time to end the bandwidth schedule.
.Pp
.Ar rate
is the bandwidth limit (in KB/s) that is enforced during the specified time.
.Pp
Multiple schedules can be string together on the command line.
If the schedules overlap, the last one takes precident.
.Sh EXAMPLES
.Cm trickle -u 10 -d 20 ncftp
.Pp
Launch
.Xr ncftp 1
limiting its upload capacity to 10 KB/s, and download capacity at 20
KB/s.
.Pp
.Cm trickle -d 50 -u 10:WSaSu130,145,1000:MTTh1200,300,96 rsync ...
.Pp
Launch
.Xr rsync 1
limiting the bandwidth as follows:
.Bl -bullet
.It
constant 50 KB/s download limit
.It
1000 KB/s upload limit between 1:30 AM and 1:45 AM on Wednesdays, Saturdays, and Sundays
.It
96 KB/s upload limit between 12:00 noon and 3:00 PM on Mondays, Tuesdays, and Thursdays
.It
10 KB/s upload limit otherwise
.El
.Pp
.Cm trickle -s -u 100 -d 10000:900,1700,10" wget ...
.Pp
Launch
.Xr wget 1
in standalone mode, limiting the bandwidth as follows:
.Bl -bullet
.It
constant 100 KB/s upload limit
.It
10 KB/s download limit between 9:00 AM and 5:00 PM all days of the week
.It
10,000 KB/s download limit otherwise
.El
.\" This next request is for sections 2 and 3 function return values only.
.\" .Sh RETURN VALUES
.\" The next request is for sections 2 and 3 error and signal handling only.
Expand Down
3 changes: 3 additions & 0 deletions trickle.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@

#define TRICKLE_WOULDBLOCK 1

//each division is 5 minutes
#define DIVS_PER_HOUR 12

#endif /* !TRICKLE_H */
Loading