From c4bccb4f1589e405a647765c9d0eb882ec46cb91 Mon Sep 17 00:00:00 2001 From: rd235 Date: Mon, 14 Nov 2005 11:56:50 +0000 Subject: [PATCH] packetq beta. (vde.h: uncomment VDE_PQ to test it) git-svn-id: https://vde.svn.sourceforge.net/svnroot/vde/trunk@61 d37a7db1-d92d-0410-89df-f68f52f87b57 --- vde-2/INSTALL | 5 ++ vde-2/Makefile.am | 2 + vde-2/datasock.c | 14 ++++-- vde-2/datasock.h | 2 +- vde-2/packetq.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++ vde-2/packetq.h | 21 ++++++++ vde-2/port.c | 20 +++++++- vde-2/port.h | 2 +- vde-2/tuntap.c | 14 ++++-- vde-2/tuntap.h | 2 +- vde-2/vde.h | 1 + vde-2/vde_switch.c | 17 ++++++- 12 files changed, 231 insertions(+), 12 deletions(-) create mode 100644 vde-2/packetq.c create mode 100644 vde-2/packetq.h diff --git a/vde-2/INSTALL b/vde-2/INSTALL index c42ef9c..6ff5ce2 100644 --- a/vde-2/INSTALL +++ b/vde-2/INSTALL @@ -12,3 +12,8 @@ then: $ make and if you want: $ make install + + +MACOS 10.3: +these extra tools must be installed first: +autoconf-2.59,automake-1.9,libtool-1.5.20 diff --git a/vde-2/Makefile.am b/vde-2/Makefile.am index c2c0c11..3200b42 100644 --- a/vde-2/Makefile.am +++ b/vde-2/Makefile.am @@ -29,6 +29,8 @@ vde_switch_SOURCES = \ consmgmt.h \ fstp.c \ fstp.h \ + packetq.c \ + packetq.h \ bitarray.h dpipe_SOURCES = dpipe.c vde_plug_SOURCES = vde_plug.c vde.h diff --git a/vde-2/datasock.c b/vde-2/datasock.c index 152eb03..4ae61e7 100644 --- a/vde-2/datasock.c +++ b/vde-2/datasock.c @@ -75,15 +75,23 @@ union request { struct request_v3 v3; }; -static void send_datasock(int fd, int ctl_fd, void *packet, int len, void *data, int port) +static int send_datasock(int fd, int ctl_fd, void *packet, int len, void *data, int port) { int n; struct sockaddr *dst=(struct sockaddr *)data; - n = sendto(fd, packet, len, 0, dst, sizeof(struct sockaddr_un)); - if(n != len){ + n = len - sendto(fd, packet, len, 0, dst, sizeof(struct sockaddr_un)); + if(n){ + int rv=errno; +#ifndef VDE_PQ if(errno != EAGAIN) printlog(LOG_WARNING,"send_sockaddr port %d: %s",port,strerror(errno)); +#endif + if (n>len) + return -rv; + else + return n; } + return 0; } static void closeport(int fd, int portno) diff --git a/vde-2/datasock.h b/vde-2/datasock.h index a49b8ff..d29a587 100644 --- a/vde-2/datasock.h +++ b/vde-2/datasock.h @@ -5,7 +5,7 @@ #ifndef __TUNTAP_H__ #define __TUNTAP_H__ -void send_datasock(int fd, int ctl_fd, void *packet, int len, void *unused, int port); +int send_datasock(int fd, int ctl_fd, void *packet, int len, void *unused, int port); int recv_datasock(int_fd, void *packet, int maxlen, int port); int open_datasock(char *dev); diff --git a/vde-2/packetq.c b/vde-2/packetq.c new file mode 100644 index 0000000..dc895c2 --- /dev/null +++ b/vde-2/packetq.c @@ -0,0 +1,143 @@ +/* + * packetq - packet queue management. try to send packets several times before discarding. + * Copyright 2005 Renzo Davoli + * Licensed under the GPLv2 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef VDE_PQ +#include "packetq.h" + +int packetq_timeout= -1; +#define TIMEOUT 5 +#define TIMES 10 + +struct packetqq { + int (*sender)(int fd, int fd_ctl, void *packet, int len, void *data, int port); + int fd; + int fd_ctl; + void *packet; + int len; + void *data; + int port; + int times; + struct packetqq *next; +}; + +static struct packetqq *pqh=NULL; +static struct packetqq *pqt=NULL; +static struct timeval last_try; + +void packetq_add(int (*sender)(int fd, int fd_ctl, void *packet, int len, void *data, int port), + int fd, int fd_ctl, void *packet, int len, void *data, int port) +{ + struct packetqq *new=malloc(sizeof(struct packetqq)); + void *packetcopy=malloc(len); + if (new != NULL && packetcopy != NULL && len > 0) { + new->sender=sender; + new->fd=fd; + new->fd_ctl=fd_ctl; + memcpy(packetcopy,packet,len); + new->packet=packetcopy; + new->len=len; + new->data=data; + new->port=port; + new->times=TIMES; + new->next=NULL; + if (pqh==NULL) { + gettimeofday(&last_try,NULL); + packetq_timeout=TIMEOUT; + pqh=pqt=new; + } else { + pqt->next=new; + pqt=new; + } + } else { + if (new != NULL) free(new); + if (packetcopy != NULL) free(packetcopy); + } +} + +static struct packetqq *packetq_scantry(struct packetqq *h,struct packetqq **t) +{ + if (h != NULL) { + int sendrv; + h->times--; + if ((sendrv=h->sender(h->fd,h->fd_ctl,h->packet,h->len,h->data,h->port)) == 0 /*send OK*/ + || h->times==0) { /*or max number of attempts reached*/ + struct packetqq *next; + if (sendrv != 0) { + if (sendrv < 0) + printlog(LOG_WARNING,"packetqueue port %d: %s",h->port,strerror(-sendrv)); + else + printlog(LOG_WARNING,"packetqueue port %d: partial send (%d bytes lost)",h->port,sendrv); + } + next=h->next; + free(h->packet); + free(h); + return packetq_scantry(next,t); + } else { + h->next=packetq_scantry(h->next,t); + if (h->next == NULL) *t=h; + return h; + } + } else + return NULL; +} + +void packetq_try(void) +{ + struct timeval this_try; + if (pqh != NULL) { + gettimeofday(&this_try,NULL); + packetq_timeout=TIMEOUT - ((this_try.tv_sec-last_try.tv_sec) * 1000 + + (this_try.tv_usec-last_try.tv_usec) / 1000); + if (packetq_timeout <= 0) { + pqh=packetq_scantry(pqh,&pqt); + if (pqh != NULL) { + gettimeofday(&last_try,NULL); + packetq_timeout=TIMEOUT; + } else + packetq_timeout = -1; + } + } +} + +static struct packetqq *packetq_scandelfd(int fd,struct packetqq *h,struct packetqq **t) +{ + if (h != NULL) { + h->times--; + if (fd == h->fd) { + struct packetqq *next=h->next; + free(h->packet); + free(h); + return packetq_scandelfd(fd,next,t); + } else { + h->next=packetq_scandelfd(fd,h->next,t); + if (h->next == NULL) *t=h; + return h; + } + } else + return NULL; +} + +void packetq_delfd(int fd) +{ + pqh=packetq_scandelfd(fd,pqh,&pqt); + if (pqh == NULL) + packetq_timeout = -1; +} + +#endif diff --git a/vde-2/packetq.h b/vde-2/packetq.h new file mode 100644 index 0000000..b06c4bd --- /dev/null +++ b/vde-2/packetq.h @@ -0,0 +1,21 @@ +/* + * packetq - packet queue management. try to send packets several times before discarding. + * Copyright 2005 Renzo Davoli + * Licensed under the GPLv2 + */ + +#ifdef VDE_PQ +#ifndef _PACKETQ_H +#define _PACKETQ_H + +extern int packetq_timeout; + +void packetq_add(int (*sender)(int fd, int fd_ctl, void *packet, int len, void *data, int port), + int fd, int fd_ctl, void *packet, int len, void *data, int port); + +void packetq_try(void); + +void packetq_delfd(int fd); + +#endif +#endif diff --git a/vde-2/port.c b/vde-2/port.c index 6dfe7eb..7087161 100644 --- a/vde-2/port.c +++ b/vde-2/port.c @@ -23,6 +23,10 @@ #include #include #include +#include +#ifdef VDE_PQ +#include +#endif static int pflag=0; static int numports; @@ -60,7 +64,7 @@ struct port { struct endpoint *ep; int flag; /* sender is already inside ep, but it needs one more memaccess */ - void (*sender)(int fd, int fd_ctl, void *packet, int len, void *data, int port); + int (*sender)(int fd, int fd_ctl, void *packet, int len, void *data, int port); struct mod_support *ms; int vlanuntag; #ifdef FSTP @@ -230,6 +234,9 @@ int close_ep(int portno, int fd_ctl) int rv=rec_close_ep(&(port->ep),fd_ctl); if (port->ep == NULL) { hash_delete_port(portno); +#ifdef VDE_PQ + packetq_delfd(port->fd_data); +#endif if (portv[portno]->ms->delport) portv[portno]->ms->delport(port->fd_data,portno); port->fd_data=-1; @@ -266,6 +273,16 @@ int portflag(int op,int f) /*********************** sending macro used by Core ******************/ +#ifdef VDE_PQ +#define SEND_PACKET_PORT(PORT,PACKET,LEN) \ + ({ \ + struct port *Port=(PORT); \ + struct endpoint *ep; \ + for (ep=Port->ep; ep != NULL; ep=ep->next) \ + if (Port->ms->sender(Port->fd_data, ep->fd_ctl, (PACKET), (LEN), ep->data, ep->port)) \ + packetq_add(Port->ms->sender,Port->fd_data, ep->fd_ctl, (PACKET), (LEN), ep->data, ep->port); \ + }) +#else #define SEND_PACKET_PORT(PORT,PACKET,LEN) \ ({ \ struct port *Port=(PORT); \ @@ -273,6 +290,7 @@ int portflag(int op,int f) for (ep=Port->ep; ep != NULL; ep=ep->next) \ Port->ms->sender(Port->fd_data, ep->fd_ctl, (PACKET), (LEN), ep->data, ep->port); \ }) +#endif #ifdef FSTP diff --git a/vde-2/port.h b/vde-2/port.h index 5fd2003..9a3a395 100644 --- a/vde-2/port.h +++ b/vde-2/port.h @@ -37,7 +37,7 @@ struct bipacket { struct mod_support { char *modname; - void (*sender)(int fd, int fd_ctl, void *packet, int len, void *data, int port); + int (*sender)(int fd, int fd_ctl, void *packet, int len, void *data, int port); int (*newport)(int fd_ctl,int portno); void (*delep)(int fd, void* data, void *descr); void (*delport)(int fd,int portno); diff --git a/vde-2/tuntap.c b/vde-2/tuntap.c index 8467bca..0cd50d0 100644 --- a/vde-2/tuntap.c +++ b/vde-2/tuntap.c @@ -48,14 +48,22 @@ struct init_tap { struct init_tap *hinit_tap=NULL; -static void send_tap(int fd, int ctl_fd, void *packet, int len, void *unused, int port) +static int send_tap(int fd, int ctl_fd, void *packet, int len, void *unused, int port) { int n; - n = write(ctl_fd, packet, len); - if(n != len){ + n = len - write(ctl_fd, packet, len); + if(n){ + int rv=errno; +#ifndef VDE_PQ if(errno != EAGAIN) printlog(LOG_WARNING,"send_tap port %d: %s",port,strerror(errno)); +#endif + if (n > len) + return -rv; + else + return n; } + return 0; } static void closeport(int fd, int portno) diff --git a/vde-2/tuntap.h b/vde-2/tuntap.h index 103c27b..4f826a5 100644 --- a/vde-2/tuntap.h +++ b/vde-2/tuntap.h @@ -5,7 +5,7 @@ #ifndef __TUNTAP_H__ #define __TUNTAP_H__ -extern void send_tap(int fd, int ctl_fd, void *packet, int len, void *unused, int port); +extern int send_tap(int fd, int ctl_fd, void *packet, int len, void *unused, int port); extern int recv_tap(int fd, void *packet, int maxlen, int port); extern int open_tap(char *dev); diff --git a/vde-2/vde.h b/vde-2/vde.h index 8cdf415..f7d5f70 100644 --- a/vde-2/vde.h +++ b/vde-2/vde.h @@ -14,5 +14,6 @@ #define DO_SYSLOG #define VDE_IP_LOG +//#define VDE_PQ #endif diff --git a/vde-2/vde_switch.c b/vde-2/vde_switch.c index f31130f..7d84836 100644 --- a/vde-2/vde_switch.c +++ b/vde-2/vde_switch.c @@ -30,6 +30,9 @@ #include #include +#ifdef VDE_PQ +#include +#endif #ifdef HAVE_BROKEN_POLL #include "poll2select.h" @@ -206,12 +209,16 @@ static void main_loop() time_t now; register int n,i; while(1) { +#ifdef VDE_PQ + n=poll(fds,nfds,packetq_timeout); +#else n=poll(fds,nfds,-1); +#endif now=qtime(); if(n < 0){ if(errno != EINTR) printlog(LOG_WARNING,"poll %s",strerror(errno)); - } else + } else { for(i = 0; /*i < nfds &&*/ n>0; i++){ if(fds[i].revents != 0) { register int prenfds=nfds; @@ -219,8 +226,9 @@ static void main_loop() fdpp[i]->timestamp=now; TYPE2MGR(fdpp[i]->type)->handle_input(fdpp[i]->type,fds[i].fd,fds[i].revents,&(fdpp[i]->arg)); if (nfds!=prenfds) /* the current fd has been deleted */ - break; /* PERFORMANCE it is faster to return to poll */ + break; /* PERFORMANCE it is faster returning to poll */ } +/* optimization: most used descriptors migrate to the head of the poll array */ #ifdef OPTPOLL else { @@ -236,6 +244,11 @@ static void main_loop() } #endif } +#ifdef VDE_PQ + if (packetq_timeout > 0) + packetq_try(); +#endif + } } } -- 2.11.4.GIT