From e09ae256821438fddcdde5b55ee30417a4c0a683 Mon Sep 17 00:00:00 2001 From: rd235 Date: Thu, 14 May 2009 14:41:01 +0000 Subject: [PATCH] Wirefilter: new markov mode (see man page) git-svn-id: https://vde.svn.sourceforge.net/svnroot/vde/trunk@364 d37a7db1-d92d-0410-89df-f68f52f87b57 --- vde-2/man/wirefilter.1 | 78 +++++++- vde-2/src/wirefilter.c | 507 ++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 474 insertions(+), 111 deletions(-) diff --git a/vde-2/man/wirefilter.1 b/vde-2/man/wirefilter.1 index b010c50..ec4a896 100644 --- a/vde-2/man/wirefilter.1 +++ b/vde-2/man/wirefilter.1 @@ -4,6 +4,7 @@ wirefilter \- Wire packet filter for Virtual Distributed Ethernet .SH SYNOPSIS .B wirefilter +[\fB\-f\fI rcfile\fR] [\fB\-l\fI loss\fR] [\fB\-l\fI lostburst\fR] [\fB\-d\fI delay\fR] @@ -40,6 +41,13 @@ wirefilter -v /tmp/s1:/tmp/s2 -l 10 .SH OPTIONS .TP +.B \-f "\fIrcfile\fP" +use a startup configuration file. It is useful for complex defitions +such as those for the Markov mode (see below). +The startup configuration file has the same syntax of the management +interface, in other word it is a script of management commands executed +before the first packet is forwarded. +.TP .B \-l "\fIloss\fP" percentage of loss as a floating point number. It is possible to specify different loss percentage for the two channels: LR20.5 means 20.5% of packet @@ -100,10 +108,14 @@ changed runtime. unixterm(1) can be used as a remote terminal for wirefilter. .TP .B \-v "\fIvde_plug1:vde_plug2\fP" If this option is used, the two local vde_plugs (vde_plug1 and vde_plug2) will be connected each other instead of stdin/stdout, -using the libvdeplug libraries. +using the libvdeplug libraries. This option activates an interactive +management session on console (stdin/stdout). .TP .B \--mgmtmode "\fImode\fP" this option sets the access mode of the mgmt socket. +The command syntax is quite simple. \fBhelp\fR provides the +list of commands. +It is possible to load a script file using the \fBload\fR management command. .TP .B \--daemon\fP wirefilter becomes a daemon @@ -131,12 +143,74 @@ e.g: .fi .in .sp +.SH Markov mode +wirefilter provides also a more complex set of parameters using a Markov +chain to emulate different states of the link and the tranistions between +states. Each state is represented by a node. +Markov chain parameters can be set with management commands or rc files only. +In fact, due to the large number of parameters the command line would have +been unreadable. +.TP +.B markov-numnodes "\fIn\fP" +defines the number of different states. All the parameters of the connection +can be defined node by node. Nodes are numbered starting from zero (to n-1). +e.g.: +.sp +.in +4in +.nf +delay 100+10N[4] +loss 10[2] +.fi +.in +.sp +these command define a delay of 90-110 ms (normal distribution) for the node +number 4 and a 10\% loss for the node 2. +It is possible to resize the Markov chain at run-time. +New nodes are unreachable and do not have any edge to other states (i.e. +each new node has a loopback edge to the node itself with 100% probability). +When reducing the number of nodes, the weight of the edges towards deleted +nodes is added to the loopback edge. When the current node of the +emulation is deleted, node 0 becomes the current node. +(The emulation always starts from node 0). +.TP +.B markov-time "\fIms\fP" +time period (ms) for the markov chain computation. Each $ms$ microseconds +a random number generator decides which is the next state. +.TP +.B markov-name "\fIn,name\fP" +assign a name to a node of the markov chain. +.TP +.B markov-setnode "\fIn\fP" +manually set the current node to the node \fIn\fP. +.TP +.B setedge "\fIn1,n2,w\fP" +define an edge between $n1$ and $n2$. $w$ is the weight (probability percentage) +of the edge. +The loopback edge (from a node to itself) is always computed as 100% minus +the sum of the weights of outgoing edges. +.TP +.B showedges [ "\fIn\fP" ] +list the edges from node \fIn\fP (or from the current node when the command +has no parameters). Null weight edges are omitted. +.TP +.B showcurrent +show the current Markov state. +.TP +.B showinfo [ \fIn\fP ] +show status and information on state (node) \fIn\fP. +If the parameter is omitted +it shows the status and information on the current state. +.TP +.B markov-debug [ \fIn\fP ] +set the debug level for the current management connection. +In the actual implementation when n is greater than zero each +change of markov node causes the output of a debug trace. +Debug tracing get disabled when \fIn\fP is zero or the parameter is missing. .SH NOTICE Virtual Distributed Ethernet is not related in any way with www.vde.com ("Verband der Elektrotechnik, Elektronik und Informationstechnik" i.e. the German "Association for Electrical, Electronic & Information Technologies"). - .SH SEE ALSO \fBvde_switch\fP(1), \fBvdeq\fP(1). diff --git a/vde-2/src/wirefilter.c b/vde-2/src/wirefilter.c index 448efa3..95bed90 100644 --- a/vde-2/src/wirefilter.c +++ b/vde-2/src/wirefilter.c @@ -2,6 +2,7 @@ * Licensed under the GPLv2 * Modified by Ludovico Gardenghi 2005 * Modified by Renzo Davoli, Luca Bigliardi 2007 + * Modified by Renzo Davoli, Luca Raggi 2009 (Markov chain support) * Gauss normal distribution/blinking support, requested and parlty implemented * by Luca Saiu and Jean-Vincent Loddo (Marionnet project) * Gilbert model for packet loss requested by Leandro Galvao. @@ -53,8 +54,9 @@ static int alternate_stdin; static int alternate_stdout; #define NPFD NPIPES+NPIPES+MAXCONN+1 -struct pollfd pfd[NPFD]; +struct pollfd pfd[NPFD]={[0 ... NPFD-1 ]={.fd=-1}}; int outfd[NPIPES]; +char debuglevel[NPFD]; char *progname; char *mgmt; int mgmtmode=0700; @@ -69,27 +71,36 @@ struct wirevalue { char alg; }; -static inline double max_wirevalue(struct wirevalue *val) -{ - return (val->value + val->plus); -} - -static inline double min_wirevalue(struct wirevalue *val) -{ - return (val->value - val->plus); -} - -struct wirevalue loss[2]; -struct wirevalue lostburst[2]; -struct wirevalue delay[2]; -struct wirevalue ddup[2]; -struct wirevalue band[2]; -struct wirevalue speed[2]; -struct wirevalue speed[2]; -struct wirevalue capacity[2]; -struct wirevalue noise[2]; -struct wirevalue mtu[2]; -/*for the Gilber model */ +#define LOSS 0 +#define LOSTBURST 1 +#define DELAY 2 +#define DDUP 3 +#define BAND 4 +#define SPEED 5 +#define CAPACITY 6 +#define NOISE 7 +#define MTU 8 +#define NUMVALUES 9 + +/* general Markov chain approach */ +int markov_numnodes=0; +int markov_current=0; +struct markov_node { + char *name; + struct wirevalue val[NUMVALUES][2]; +}; +double *adjmap; +#define ADJMAPN(M,I,J,N) (M)[(I)*(N)+(J)] +#define ADJMAP(I,J) ADJMAPN(adjmap,(I),(J),markov_numnodes) +#define ROT(I,J) (((I)+(J))%markov_numnodes) +struct markov_node **markov_nodes; +#define WFVAL(N,T,D) (markov_nodes[N]->val[T][D]) +#define WFADDR(N,T) (markov_nodes[N]->val[T]) +#define WFNAME(N) (markov_nodes[N]->name) +double markov_time=100.0; +long long markov_next; + +/*for the Gilbert model */ #define OK_BURST 0 #define FAULTY_BURST 1 char loss_status[2]; /* Gilbert model Markov chain status */ @@ -110,6 +121,120 @@ static struct sockaddr_un blinksun; static char *blinkmsg; static char blinkidlen; +static void printoutc(int fd, const char *format, ...); +/* markov node mgmt */ +static inline struct markov_node *markov_node_new(void) +{ + return calloc(1,sizeof(struct markov_node)); +} + +static inline void markov_node_free(struct markov_node *old) +{ + free(old); +} + +static void markov_compute(i) +{ + int j; + ADJMAP(i,i)=100.0; + for (j=1;jmarkov_numnodes) { + markov_nodes=realloc(markov_nodes,numnodes*(sizeof(struct markov_node *))); + for (i=markov_numnodes;i= numnodes) + markov_current = 0; + } + copyadjmap(numnodes,newadjmap); + if (adjmap) + free(adjmap); + adjmap=newadjmap; + markov_numnodes=numnodes; + } +} + +static int markov_step(int i) { + double num=drand48() * 100; + int j,k=0; + markov_next+=markov_time; + for (j=0;j 0) { + int fd=pfd[j].fd; + if (fd == 0) fd=1; + printoutc(fd,"%04d Node %d \"%s\" -> %d \"%s\"", + 3800+k, + i, WFNAME(i)?WFNAME(i):"", + k, WFNAME(k)?WFNAME(k):""); + } + } + } + return k; +} + +static int markovms(void) { + if (markov_numnodes > 1) { + struct timeval v; + gettimeofday(&v,NULL); + unsigned long long next=markov_next-(v.tv_sec*1000+v.tv_usec/1000); + if (next < 0) next=0; + return next; + } else + return -1; +} + +static inline void markov_try(void) { + if (markov_numnodes > 1) { + struct timeval v; + gettimeofday(&v,NULL); + if ((markov_next-(v.tv_sec*1000+v.tv_usec/1000)) <= 0) + markov_current=markov_step(markov_current); + } +} + +static void markov_start(void) { + if (markov_numnodes > 1) { + struct timeval v; + gettimeofday(&v,NULL); + markov_next=v.tv_sec*1000+v.tv_usec/1000; + markov_current=markov_step(markov_current); + } +} + #define BUFSIZE 2048 #define MAXCMD 128 #define MGMTMODEARG 129 @@ -121,6 +246,16 @@ static char blinkidlen; #define MEGA (1<<20) #define GIGA (1<<30) +static inline double max_wirevalue(int node,int tag, int dir) +{ + return (WFVAL(node,tag,dir).value + WFVAL(node,tag,dir).plus); +} + +static inline double min_wirevalue(int node,int tag, int dir) +{ + return (WFVAL(node,tag,dir).value - WFVAL(node,tag,dir).plus); +} + static void initrand() { struct timeval v; @@ -130,8 +265,9 @@ static void initrand() /*more than 98% inside the bell */ #define SIGMA (1.0/3.0) -static double compute_wirevalue(struct wirevalue *wv) +static double compute_wirevalue(int tag, int dir) { + struct wirevalue *wv=&WFVAL(markov_current,tag,dir); if (wv->plus == 0) return wv->value; switch (wv->alg) { @@ -168,8 +304,10 @@ void printlog(int priority, const char *format, ...) va_end (arg); } -static void read_wirevalue(char *s,struct wirevalue *wv) +static int read_wirevalue(char *s, int tag) { + struct wirevalue *wv; + int markov_node=0; double v=0.0; double vplus=0.0; int n; @@ -177,10 +315,19 @@ static void read_wirevalue(char *s,struct wirevalue *wv) char algo=ALGO_UNIFORM; n=strlen(s)-1; while ((s[n] == ' ' || s[n] == '\n' || s[n] == '\t') && n>0) + s[n--]=0; + if (s[n]==']') { - s[n]=0; - n--; + char *idstr=&s[n]; + s[n--] = 0; + while(s[n]!='[' && n>1) + idstr = &s[n--]; + s[n--] = 0; + sscanf(idstr,"%d",&markov_node); + if (markov_node < 0 || markov_node >= markov_numnodes) + return EINVAL; } + wv=WFADDR(markov_node,tag); switch (s[n]) { case 'u': case 'U': @@ -223,6 +370,7 @@ static void read_wirevalue(char *s,struct wirevalue *wv) wv[RL].plus=vplus*mult; wv[RL].alg=algo; } + return 0; } struct packpq { @@ -269,8 +417,8 @@ static inline int outpacket(int dir,const unsigned char *buf,int size) int writepacket(int dir,const unsigned char *buf,int size) { /* NOISE */ - if (max_wirevalue(noise+dir) > 0) { - double noiseval=compute_wirevalue(noise+dir); + if (max_wirevalue(markov_current,NOISE,dir) > 0) { + double noiseval=compute_wirevalue(NOISE,dir); int nobit=0; while ((drand48()*8*MEGA) < (size-2)*8*noiseval) nobit++; @@ -325,8 +473,8 @@ static void packet_enqueue(int dir,const unsigned char *buf,int size,int delms) /* CAPACITY */ /* when bandwidth is limited, packets exceeding capacity are discarded */ - if (max_wirevalue(capacity+dir) > 0) { - double capval=compute_wirevalue(capacity+dir); + if (max_wirevalue(markov_current,CAPACITY,dir) > 0) { + double capval=compute_wirevalue(CAPACITY,dir); if ((delay_bufsize[dir]+size) > capval) return; } @@ -378,18 +526,18 @@ void handle_packet(int dir,const unsigned char *buf,int size) { /* MTU */ /* if the packet is incosistent with the MTU of the line just drop it */ - if (min_wirevalue(mtu+dir) > 0 && size > min_wirevalue(mtu+dir)) + if (min_wirevalue(markov_current,MTU,dir) > 0 && size > min_wirevalue(markov_current,MTU,dir)) return; /* LOSS */ /* Total packet loss */ - if (min_wirevalue(loss+dir) >= 100.0) + if (min_wirevalue(markov_current,LOSS,dir) >= 100.0) return; /* probabilistic loss */ - if (max_wirevalue(lostburst+dir) > 0) { + if (max_wirevalue(markov_current,LOSTBURST,dir) > 0) { /* Gilbert model */ - double losval=compute_wirevalue(loss+dir)/100; - double burstlen=compute_wirevalue(lostburst+dir); + double losval=compute_wirevalue(LOSS,dir)/100; + double burstlen=compute_wirevalue(LOSTBURST,dir); double alpha=losval / (burstlen*(1-losval)); double beta=1.0 / burstlen; switch (loss_status[dir]) { @@ -402,18 +550,21 @@ void handle_packet(int dir,const unsigned char *buf,int size) } if (loss_status[dir] != OK_BURST) return; - } else if (max_wirevalue(loss+dir) > 0) { - /* standard non bursty model */ - double losval=compute_wirevalue(loss+dir)/100; - if (drand48() < losval) - return; + } else { + loss_status[dir] = OK_BURST; + if (max_wirevalue(markov_current,LOSS,dir) > 0) { + /* standard non bursty model */ + double losval=compute_wirevalue(LOSS,dir)/100; + if (drand48() < losval) + return; + } } /* DUP */ /* times is the number of dup packets */ int times=1; - if (max_wirevalue(ddup+dir) > 0) { - double dupval=compute_wirevalue(ddup+dir)/100; + if (max_wirevalue(markov_current,DDUP,dir) > 0) { + double dupval=compute_wirevalue(DDUP,dir)/100; while (drand48() < dupval) times++; } @@ -422,8 +573,8 @@ void handle_packet(int dir,const unsigned char *buf,int size) /* SPEED */ /* speed limit, if packets arrive too fast, delay the sender */ - if (max_wirevalue(speed+dir) > 0) { - double speedval=compute_wirevalue(speed+dir); + if (max_wirevalue(markov_current,SPEED,dir) > 0) { + double speedval=compute_wirevalue(SPEED,dir); if (speedval<=0) return; if (speedval>0) { unsigned int commtime=((unsigned)size)*1000000/((unsigned int)speedval); @@ -440,8 +591,8 @@ void handle_packet(int dir,const unsigned char *buf,int size) /* BANDWIDTH */ /* band, when band overflows, delay just the delivery */ - if (max_wirevalue(band+dir) > 0) { - double bandval=compute_wirevalue(band+dir); + if (max_wirevalue(markov_current,BAND,dir) > 0) { + double bandval=compute_wirevalue(BAND,dir); if (bandval<=0) return; if (bandval >0) { unsigned int commtime=((unsigned)size)*1000000/((unsigned int)bandval); @@ -464,8 +615,8 @@ void handle_packet(int dir,const unsigned char *buf,int size) /* DELAY */ /* line delay */ if (banddelay >= 0) { - if (banddelay > 0 || max_wirevalue(delay+dir) > 0) { - double delval=compute_wirevalue(delay+dir); + if (banddelay > 0 || max_wirevalue(markov_current,DELAY,dir) > 0) { + double delval=compute_wirevalue(DELAY,dir); delval=(delval >= 0)?delval+banddelay:banddelay; if (delval > 0) { packet_enqueue(dir,buf,size,(int) delval); @@ -773,6 +924,7 @@ static int newmgmtconn(int fd,struct pollfd *pfd,int nfds) write(new,prompt,strlen(prompt)); pfd[nfds].fd=new; pfd[nfds].events=POLLIN | POLLHUP; + debuglevel[nfds]=0; return ++nfds; } else { printlog(LOG_WARNING,"too many mgmt connections"); @@ -794,60 +946,47 @@ static void printoutc(int fd, const char *format, ...) static int setdelay(int fd,char *s) { - read_wirevalue(s,delay); - return 0; + return read_wirevalue(s,DELAY); } static int setloss(int fd,char *s) { - read_wirevalue(s,loss); - return 0; + return read_wirevalue(s,LOSS); } static int setlostburst(int fd,char *s) { - read_wirevalue(s,lostburst); - if (max_wirevalue(lostburst+LR) == 0) - loss_status[LR]=OK_BURST; - if (max_wirevalue(lostburst+RL) == 0) - loss_status[RL]=OK_BURST; - return 0; + return read_wirevalue(s,LOSTBURST); } static int setddup(int fd,char *s) { - read_wirevalue(s,ddup); - return 0; + return read_wirevalue(s,DDUP); } static int setband(int fd,char *s) { - read_wirevalue(s,band); - return 0; + return read_wirevalue(s,BAND); } static int setnoise(int fd,char *s) { - read_wirevalue(s,noise); - return 0; + return read_wirevalue(s,NOISE); } static int setmtu(int fd,char *s) { - read_wirevalue(s,mtu); - return 0; + return read_wirevalue(s,MTU); } static int setspeed(int fd,char *s) { - read_wirevalue(s,speed); - return 0; + return read_wirevalue(s,SPEED); } static int setcapacity(int fd,char *s) { - read_wirevalue(s,capacity); - return 0; + return read_wirevalue(s,CAPACITY); } static int setfifo(int fd,char *s) @@ -860,6 +999,100 @@ static int setfifo(int fd,char *s) return 0; } +static int setmarkov_resize(int fd,char *s) +{ + int n=atoi(s); + if (n>0) { + markov_resize(n); + markov_start(); + return 0; + } else + return EINVAL; +} + +static int setedge(int fd,char *s) +{ + int x,y; + double weight; + sscanf(s,"%d,%d,%lg",&x,&y,&weight); + if (x>=0 && x=0 && y 0) { + markov_time=newvalue; + markov_start(); + return 0; + } else + return EINVAL; +} + +static int setmarkov_node(int fd,char *s) +{ + int n=atoi(s); + if (n>=0 && n= 0 && n>=0) { + int i; + if (fd==1) fd=0; + for (i=0;i=0 && nvalue,(X)->plus,(charalgo[(int)((X)->alg)]) +#define WIREVALUE_X_FIELDS(X) (X)->value,(X)->plus,(charalgo[(int)((X)->alg)]) +#define WIREVALUE_FIELDS(N,T,D) WIREVALUE_X_FIELDS(WFADDR(N,T)+D) static int showinfo(int fd,char *s) { + int node=0; + if (*s != 0) + node=atoi(s); + else + node=markov_current; + if (node >= markov_numnodes || node < 0) + return EINVAL; printoutc(fd, "WireFilter: %sdirectional",(ndirs==2)?"bi":"mono"); + if (markov_numnodes > 1) { + printoutc(fd, "Node %d \"%s\" (0,..,%d) Markov-time %lg",node, + WFNAME(node)?WFNAME(node):"",markov_numnodes-1,markov_time); + } if (ndirs==2) { printoutc(fd, "Loss L->R %g+%g%c R->L %g+%g%c", - WIREVALUE_FIELDS(loss+LR), - WIREVALUE_FIELDS(loss+RL)); + WIREVALUE_FIELDS(node,LOSS,LR), + WIREVALUE_FIELDS(node,LOSS,RL)); printoutc(fd, "Lburst L->R %g+%g%c R->L %g+%g%c", - WIREVALUE_FIELDS(lostburst+LR), - WIREVALUE_FIELDS(lostburst+RL)); + WIREVALUE_FIELDS(node,LOSTBURST,LR), + WIREVALUE_FIELDS(node,LOSTBURST,RL)); printoutc(fd, "Delay L->R %g+%g%c R->L %g+%g%c", - WIREVALUE_FIELDS(delay+LR), - WIREVALUE_FIELDS(delay+RL)); + WIREVALUE_FIELDS(node,DELAY,LR), + WIREVALUE_FIELDS(node,DELAY,RL)); printoutc(fd, "Dup L->R %g+%g%c R->L %g+%g%c", - WIREVALUE_FIELDS(ddup+LR), - WIREVALUE_FIELDS(ddup+RL)); + WIREVALUE_FIELDS(node,DDUP,LR), + WIREVALUE_FIELDS(node,DDUP,RL)); printoutc(fd, "Bandw L->R %g+%g%c R->L %g+%g%c", - WIREVALUE_FIELDS(band+LR), - WIREVALUE_FIELDS(band+RL)); + WIREVALUE_FIELDS(node,BAND,LR), + WIREVALUE_FIELDS(node,BAND,RL)); printoutc(fd, "Speed L->R %g+%g%c R->L %g+%g%c", - WIREVALUE_FIELDS(speed+LR), - WIREVALUE_FIELDS(speed+RL)); + WIREVALUE_FIELDS(node,SPEED,LR), + WIREVALUE_FIELDS(node,SPEED,RL)); printoutc(fd, "Noise L->R %g+%g%c R->L %g+%g%c", - WIREVALUE_FIELDS(noise+LR), - WIREVALUE_FIELDS(noise+RL)); + WIREVALUE_FIELDS(node,NOISE,LR), + WIREVALUE_FIELDS(node,NOISE,RL)); printoutc(fd, "MTU L->R %g R->L %g ", - min_wirevalue(mtu+LR), - min_wirevalue(mtu+RL)); + min_wirevalue(node,MTU,LR), + min_wirevalue(node,MTU,RL)); printoutc(fd, "Cap. L->R %g+%g%c R->L %g+%g%c", - WIREVALUE_FIELDS(capacity+LR), - WIREVALUE_FIELDS(capacity+RL)); + WIREVALUE_FIELDS(node,CAPACITY,LR), + WIREVALUE_FIELDS(node,CAPACITY,RL)); printoutc(fd, "Current Delay Queue size: L->R %d R->L %d ",delay_bufsize[LR],delay_bufsize[RL]); } else { printoutc(fd, "Loss %g+%g%c", - WIREVALUE_FIELDS(loss)); + WIREVALUE_FIELDS(node,LOSS,0)); printoutc(fd, "Lburst %g+%g%c", - WIREVALUE_FIELDS(lostburst)); + WIREVALUE_FIELDS(node,LOSTBURST,0)); printoutc(fd, "Delay %g+%g%c", - WIREVALUE_FIELDS(delay)); + WIREVALUE_FIELDS(node,DELAY,0)); printoutc(fd, "Dup %g+%g%c", - WIREVALUE_FIELDS(ddup)); + WIREVALUE_FIELDS(node,DDUP,0)); printoutc(fd, "Bandw %g+%g%c", - WIREVALUE_FIELDS(band)); + WIREVALUE_FIELDS(node,BAND,0)); printoutc(fd, "Speed %g+%g%c", - WIREVALUE_FIELDS(speed)); + WIREVALUE_FIELDS(node,SPEED,0)); printoutc(fd, "Noise %g+%g%c", - WIREVALUE_FIELDS(noise)); - printoutc(fd, "MTU %g", min_wirevalue(mtu)); + WIREVALUE_FIELDS(node,NOISE,0)); + printoutc(fd, "MTU %g", min_wirevalue(node,MTU,0)); printoutc(fd, "Cap. %g+%g%c", - WIREVALUE_FIELDS(capacity)); + WIREVALUE_FIELDS(node,CAPACITY,0)); printoutc(fd, "Current Delay Queue size: %d",delay_bufsize[0]); } printoutc(fd,"Fifoness %s",(nofifo == 0)?"TRUE":"FALSE"); @@ -956,6 +1211,25 @@ static int showinfo(int fd,char *s) return 0; } +static int showedges(int fd,char *s) +{ + int node=0; + int j; + if (*s != 0) + node=atoi(s); + else + node=markov_current; + if (node >= markov_numnodes || node < 0) + return EINVAL; + for (j=0;j%-2d \"%s\"->\"%s\" weigth %lg",node,j, + WFNAME(node)?WFNAME(node):"", + WFNAME(j)?WFNAME(j):"", + ADJMAP(node,j)); + return 0; +} + static int runscript(int fd,char *path); #define WITHFILE 0x80 @@ -978,6 +1252,14 @@ static struct comlist { {"noise",setnoise, 0}, {"mtu",setmtu, 0}, {"fifo",setfifo, 0}, + {"markov-numnodes",setmarkov_resize, 0}, + {"markov-setnode",setmarkov_node, 0}, + {"markov-name",setmarkov_name, 0}, + {"markov-time",setmarkov_time, 0}, + {"setedge",setedge, 0}, + {"showedges",showedges, WITHFILE}, + {"showcurrent",showcurrent, WITHFILE}, + {"markov-debug",setmarkov_debug, 0}, {"logout",logout, 0}, {"shutdown",doshutdown, 0} }; @@ -1074,6 +1356,9 @@ static int delmgmtconn(int i,struct pollfd *pfd,int nfds) if (pfd[i].fd == 0) /* close stdin implies exit */ exit(0); memmove(pfd+i,pfd+i+1,sizeof (struct pollfd) * (nfds-i-1)); + memmove(debuglevel+i,debuglevel+i+1,sizeof(char) * (nfds-i-1)); + pfd[nfds].fd = -1; + debuglevel[nfds] = 0; nfds--; } return nfds; @@ -1134,6 +1419,7 @@ int main(int argc,char *argv[]) {"blinkid",1,0,LOGIDARG} }; progname=basename(argv[0]); + markov_resize(1); setsighandlers(); atexit(cleanup); @@ -1152,31 +1438,31 @@ int main(int argc,char *argv[]) rcfile=strdup(optarg); break; case 'd': - read_wirevalue(optarg,delay); + read_wirevalue(optarg,DELAY); break; case 'l': - read_wirevalue(optarg,loss); + read_wirevalue(optarg,LOSS); break; case 'L': - read_wirevalue(optarg,lostburst); + read_wirevalue(optarg,LOSTBURST); break; case 'D': - read_wirevalue(optarg,ddup); + read_wirevalue(optarg,DDUP); break; case 'b': - read_wirevalue(optarg,band); + read_wirevalue(optarg,BAND); break; case 'm': - read_wirevalue(optarg,mtu); + read_wirevalue(optarg,MTU); break; case 'n': - read_wirevalue(optarg,noise); + read_wirevalue(optarg,NOISE); break; case 's': - read_wirevalue(optarg,speed); + read_wirevalue(optarg,SPEED); break; case 'c': - read_wirevalue(optarg,capacity); + read_wirevalue(optarg,CAPACITY); break; case 'M': mgmt=strdup(optarg); @@ -1306,8 +1592,10 @@ int main(int argc,char *argv[]) initrand(); while(1) { int delay=nextms(); + int markovdelay=markovms(); + if (markovdelay < delay || delay < 0) delay=markovdelay; pfd[0].events |= POLLIN; - if (speed[LR].value > 0) { + if (WFVAL(markov_current,SPEED,LR).value > 0) { struct timeval tv; int speeddelay; gettimeofday(&tv,NULL); @@ -1322,7 +1610,7 @@ int main(int argc,char *argv[]) } if (ndirs > 1) { pfd[1].events |= POLLIN; - if (speed[RL].value > 0) { + if (WFVAL(markov_current,SPEED,RL).value > 0) { struct timeval tv; int speeddelay; if (timercmp(&tv, &nextspeed[RL], <)) { @@ -1369,6 +1657,7 @@ int main(int argc,char *argv[]) /* if (n>0) // if there are already pending events, it means that a ctlfd has hunged up exit(0);*/ } + markov_try(); packet_dequeue(); } } -- 2.11.4.GIT