Revision: 479 http://vde.svn.sourceforge.net/vde/?rev=479&view=rev Author: rd235 Date: 2011-03-25 18:08:57 +0000 (Fri, 25 Mar 2011)
Log Message: ----------- Step one towards a new management of packetq: data_fd are now connected sockets Modified Paths: -------------- branches/rd235/vde-2/src/vde_switch/datasock.c branches/rd235/vde-2/src/vde_switch/packetq.c branches/rd235/vde-2/src/vde_switch/packetq.h branches/rd235/vde-2/src/vde_switch/port.c branches/rd235/vde-2/src/vde_switch/port.h branches/rd235/vde-2/src/vde_switch/tuntap.c Modified: branches/rd235/vde-2/src/vde_switch/datasock.c =================================================================== --- branches/rd235/vde-2/src/vde_switch/datasock.c 2011-03-16 21:30:55 UTC (rev 478) +++ branches/rd235/vde-2/src/vde_switch/datasock.c 2011-03-25 18:08:57 UTC (rev 479) @@ -83,12 +83,11 @@ struct request_v3 v3; }; -static int send_datasock(int fd, int ctl_fd, void *packet, int len, void *data, int port) +static int send_datasock(int fd_ctl, int fd_data, void *packet, int len, int port) { int n; - struct sockaddr *dst=(struct sockaddr *)data; - n = len - sendto(fd, packet, len, 0, dst, sizeof(struct sockaddr_un)); + n = len - send(fd_data, packet, len, 0); if(n){ int rv=errno; #ifndef VDE_PQ @@ -102,85 +101,23 @@ return 0; } -static void closeport(int fd, int portno) -{ - if (fd>0) - remove_fd(fd); -} - -static int newport(int fd, int portno, uid_t user) -{ - int data_fd; - struct sockaddr_un sun; -#ifdef VDE_DARWIN - int sockbufsize = DATA_BUF_SIZE; - int optsize = sizeof(sockbufsize); -#endif - - if((data_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0){ - printlog(LOG_ERR,"socket: %s",strerror(errno)); - return -1; - } - if(fcntl(data_fd, F_SETFL, O_NONBLOCK) < 0){ - printlog(LOG_ERR,"Setting O_NONBLOCK on data fd %s",strerror(errno)); - return -1; - } - -#ifdef VDE_DARWIN - if(setsockopt(data_fd, SOL_SOCKET, SO_SNDBUF, &sockbufsize, optsize) < 0) - printlog(LOG_WARNING, "Warning: setting send buffer size on data fd %d to %d failed, expect packet loss: %s", - data_fd, sockbufsize, strerror(errno)); - if(setsockopt(data_fd, SOL_SOCKET, SO_RCVBUF, &sockbufsize, optsize) < 0) - printlog(LOG_WARNING, "Warning: setting send buffer size on data fd %d to %d failed, expect packet loss: %s", - data_fd, sockbufsize, strerror(errno)); -#endif - - sun.sun_family = AF_UNIX; - snprintf(sun.sun_path,sizeof(sun.sun_path),"%s/%03d",ctl_socket,portno); - if ((unlink(sun.sun_path) < 0 && errno != ENOENT) || - bind(data_fd, (struct sockaddr *) &sun, sizeof(sun)) < 0){ - printlog(LOG_ERR,"Binding to data socket %s",strerror(errno)); - close_ep(portno-1,fd); - return -1; - } - if (geteuid() != 0) - user = -1; - if (user != -1) - chmod(sun.sun_path,mode & 0700); - else - chmod(sun.sun_path,mode); - if(chown(sun.sun_path,user,grp_owner) < 0) { - printlog(LOG_ERR, "chown: %s", strerror(errno)); - unlink(sun.sun_path); - close_ep(portno-1,fd); - return -1; - } - - add_fd(data_fd,data_type,portno); - - return data_fd; -} - -static void *memdup(void *src,int size) -{ - void *dst=malloc(size); - if (dst != NULL) - memcpy(dst,src,size); - return dst; -} - #define GETFILEOWNER(PATH) ({\ struct stat s; \ (stat((PATH),&s)?-1:s.st_uid); \ }) -static int new_port_v1_v3(int fd, int type_port, +static int new_port_v1_v3(int fd_ctl, int type_port, struct sockaddr_un *sun_out) { - int n, port; + int n, portno; enum request_type type = type_port & 0xff; int port_request=type_port >> 8; uid_t user=-1; + int fd_data; +#ifdef VDE_DARWIN + int sockbufsize = DATA_BUF_SIZE; + int optsize = sizeof(sockbufsize); +#endif struct sockaddr_un sun_in; switch(type){ case REQ_NEW_PORT0: @@ -189,31 +126,81 @@ case REQ_NEW_CONTROL: if (sun_out->sun_path[0] != 0) { //not for unnamed sockets if (access(sun_out->sun_path,R_OK | W_OK) != 0) { //socket error - remove_fd(fd); + remove_fd(fd_ctl); return -1; } user=GETFILEOWNER(sun_out->sun_path); } - port = setup_ep(port_request, fd, memdup(sun_out,sizeof(struct sockaddr_un)), user, &modfun); - if(port<0) { - remove_fd(fd); + + if((fd_data = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0){ + printlog(LOG_ERR,"socket: %s",strerror(errno)); + remove_fd(fd_ctl); return -1; } + if(fcntl(fd_data, F_SETFL, O_NONBLOCK) < 0){ + printlog(LOG_ERR,"Setting O_NONBLOCK on data fd %s",strerror(errno)); + close(fd_data); + remove_fd(fd_ctl); + return -1; + } + +#ifdef VDE_DARWIN + if(setsockopt(fd_data, SOL_SOCKET, SO_SNDBUF, &sockbufsize, optsize) < 0) + printlog(LOG_WARNING, "Warning: setting send buffer size on data fd %d to %d failed, expect packet loss: %s", + fd_data, sockbufsize, strerror(errno)); + if(setsockopt(fd_data, SOL_SOCKET, SO_RCVBUF, &sockbufsize, optsize) < 0) + printlog(LOG_WARNING, "Warning: setting send buffer size on data fd %d to %d failed, expect packet loss: %s", + fd_data, sockbufsize, strerror(errno)); +#endif + + if (connect(fd_data, (struct sockaddr *) sun_out, sizeof(struct sockaddr_un)) < 0) { + printlog(LOG_ERR,"Connecting to client data socket %s",strerror(errno)); + close(fd_data); + remove_fd(fd_ctl); + return -1; + } + + portno = setup_ep(port_request, fd_ctl, fd_data, user, &modfun); + add_fd(fd_data,data_type,portno); + if(portno<0) { + close_ep(portno,fd_ctl); + return -1; + } sun_in.sun_family = AF_UNIX; - snprintf(sun_in.sun_path,sizeof(sun_in.sun_path),"%s/%03d",ctl_socket,port); - n = write(fd, &sun_in, sizeof(sun_in)); + snprintf(sun_in.sun_path,sizeof(sun_in.sun_path),"%s/%03d.%d",ctl_socket,portno,fd_data); + + if ((unlink(sun_in.sun_path) < 0 && errno != ENOENT) || + bind(fd_data, (struct sockaddr *) &sun_in, sizeof(struct sockaddr_un)) < 0){ + printlog(LOG_ERR,"Binding to data socket %s",strerror(errno)); + close_ep(portno,fd_ctl); + return -1; + } + if (geteuid() != 0) + user = -1; + if (user != -1) + chmod(sun_in.sun_path,mode & 0700); + else + chmod(sun_in.sun_path,mode); + if(chown(sun_in.sun_path,user,grp_owner) < 0) { + printlog(LOG_ERR, "chown: %s", strerror(errno)); + unlink(sun_in.sun_path); + close_ep(portno,fd_ctl); + return -1; + } + + n = write(fd_ctl, &sun_in, sizeof(sun_in)); if(n != sizeof(sun_in)){ printlog(LOG_WARNING,"Sending data socket name %s",strerror(errno)); - close_ep(port,fd); + close_ep(portno,fd_ctl); return -1; } if (type==REQ_NEW_PORT0) setmgmtperm(sun_in.sun_path); - return port; + return portno; break; default: printlog(LOG_WARNING,"Bad request type : %d", type); - remove_fd(fd); + remove_fd(fd_ctl); return -1; } } @@ -222,11 +209,9 @@ { if (type == data_type) { struct bipacket packet; - struct sockaddr sock; int len; - socklen_t socklen = sizeof(sock); - len=recvfrom(fd, &(packet.p), sizeof(struct packet),0, &sock, &socklen); + len=recv(fd, &(packet.p), sizeof(struct packet),0); if(len < 0){ if (errno == EAGAIN || errno == EWOULDBLOCK) return; printlog(LOG_WARNING,"Reading data: %s",strerror(errno)); @@ -292,11 +277,12 @@ printlog(LOG_WARNING,"accept %s",strerror(errno)); return; } - if(fcntl(new, F_SETFL, O_NONBLOCK) < 0){ + /* + if(fcntl(new, F_SETFL, O_NONBLOCK) < 0){ printlog(LOG_WARNING,"fcntl - setting O_NONBLOCK %s",strerror(errno)); close(new); return; - } + }*/ add_fd(new,wd_type,-1); } @@ -327,7 +313,7 @@ else printlog(LOG_WARNING,"Cleanup not removing files"); } else { if (type == data_type && arg>=0) { - snprintf(clun.sun_path,sizeof(clun.sun_path),"%s/%03d",ctl_socket,arg); + snprintf(clun.sun_path,sizeof(clun.sun_path),"%s/%03d.%d",ctl_socket,arg,fd); unlink(clun.sun_path); } close(fd); @@ -499,10 +485,10 @@ {"ds/showinfo","","show ds info",showinfo,NOARG|WITHFILE}, }; -static void delep (int fd, void* data, void *descr) +static void delep (int fd_ctl, int fd_data, void *descr) { - if (fd>=0) remove_fd(fd); - if (data) free(data); + if (fd_data>=0) remove_fd(fd_data); + if (fd_ctl>=0) remove_fd(fd_ctl); if (descr) free(descr); } @@ -517,9 +503,7 @@ swmi.handle_input=handle_input; swmi.cleanup=cleanup; modfun.sender=send_datasock; - modfun.newport=newport; modfun.delep=delep; - modfun.delport=closeport; ADDCL(cl); add_swm(&swmi); } Modified: branches/rd235/vde-2/src/vde_switch/packetq.c =================================================================== --- branches/rd235/vde-2/src/vde_switch/packetq.c 2011-03-16 21:30:55 UTC (rev 478) +++ branches/rd235/vde-2/src/vde_switch/packetq.c 2011-03-25 18:08:57 UTC (rev 479) @@ -54,12 +54,11 @@ static int countq; struct packetqq { - int (*sender)(int fd, int fd_ctl, void *packet, int len, void *data, int port); - int fd; + int (*sender)(int fd_ctl, int fd_data, void *packet, int len, int port); int fd_ctl; + int fd_data; void *packet; int len; - void *data; int port; int times; struct packetqq *next; @@ -73,8 +72,8 @@ static struct timeval last_try; #endif -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_add(int (*sender)(int fd_ctl, int fd_data, void *packet, int len, int port), + int fd_ctl, int fd_data, void *packet, int len, int port) { if (countq < MAXQLEN) { struct packetqq *new=malloc(sizeof(struct packetqq)); @@ -82,12 +81,11 @@ if (new != NULL && packetcopy != NULL && len > 0) { countq++; new->sender=sender; - new->fd=fd; new->fd_ctl=fd_ctl; + new->fd_data=fd_data; memcpy(packetcopy,packet,len); new->packet=packetcopy; new->len=len; - new->data=data; new->port=port; new->times=TIMES; new->next=NULL; @@ -119,9 +117,9 @@ static struct packetqq *packetq_scantry(struct packetqq *h,struct packetqq **t,fd_set *fds) { if (h != NULL) { - int sendrv=!(FD_ISSET(h->fd,fds)); + int sendrv=!(FD_ISSET(h->fd_data,fds)); h->times--; - if ((sendrv && (sendrv=h->sender(h->fd,h->fd_ctl,h->packet,h->len,h->data,h->port)) == 0) /*send OK*/ + if ((sendrv && (sendrv=h->sender(h->fd_ctl,h->fd_data,h->packet,h->len,h->port)) == 0) /*send OK*/ || h->times<=0) { /*or max number of attempts reached*/ struct packetqq *next; next=h->next; @@ -130,7 +128,7 @@ free(h); return packetq_scantry(next,t,fds); } else { - FD_SET(h->fd,fds); + FD_SET(h->fd_data,fds); h->next=packetq_scantry(h->next,t,fds); if (h->next == NULL) *t=h; return h; @@ -182,17 +180,17 @@ } } -static struct packetqq *packetq_scandelfd(int fd,struct packetqq *h,struct packetqq **t) +static struct packetqq *packetq_scandelfd(int fd_data,struct packetqq *h,struct packetqq **t) { if (h != NULL) { - if (fd == h->fd) { + if (fd_data == h->fd_data) { struct packetqq *next=h->next; countq--; free(h->packet); free(h); - return packetq_scandelfd(fd,next,t); + return packetq_scandelfd(fd_data,next,t); } else { - h->next=packetq_scandelfd(fd,h->next,t); + h->next=packetq_scandelfd(fd_data,h->next,t); if (h->next == NULL) *t=h; return h; } @@ -200,9 +198,9 @@ return NULL; } -void packetq_delfd(int fd) +void packetq_delfd(int fd_data) { - pqh=packetq_scandelfd(fd,pqh,&pqt); + pqh=packetq_scandelfd(fd_data,pqh,&pqt); if (pqh == NULL) #ifdef VDE_PQ_PPOLL packetq_timeout = NULL; Modified: branches/rd235/vde-2/src/vde_switch/packetq.h =================================================================== --- branches/rd235/vde-2/src/vde_switch/packetq.h 2011-03-16 21:30:55 UTC (rev 478) +++ branches/rd235/vde-2/src/vde_switch/packetq.h 2011-03-25 18:08:57 UTC (rev 479) @@ -15,8 +15,8 @@ extern int packetq_timeout; #endif -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_add(int (*sender)(int fd_ctl, int fd_data, void *packet, int len, int port), + int fd, int fd_ctl, void *packet, int len, int port); void packetq_try(void); Modified: branches/rd235/vde-2/src/vde_switch/port.c =================================================================== --- branches/rd235/vde-2/src/vde_switch/port.c 2011-03-16 21:30:55 UTC (rev 478) +++ branches/rd235/vde-2/src/vde_switch/port.c 2011-03-25 18:08:57 UTC (rev 479) @@ -80,7 +80,7 @@ struct endpoint { int port; int fd_ctl; - void *data; + int fd_data; char *descr; struct endpoint *next; }; @@ -88,11 +88,10 @@ #define NOTINPOOL 0x8000 struct port { - int fd_data; struct endpoint *ep; int flag; /* sender is already inside ms, but it needs one more memaccess */ - int (*sender)(int fd, int fd_ctl, void *packet, int len, void *data, int port); + int (*sender)(int fd_ctl, int fd_data, void *packet, int len, int port); struct mod_support *ms; int vlanuntag; uid_t user; @@ -148,7 +147,6 @@ EVENTOUT(DBGPORTNEW,i); portv[i]=port; - port->fd_data=-1; port->ep=NULL; port->user=port->group=port->curuser=-1; #ifdef FSTP @@ -185,32 +183,9 @@ } /* 1 if user belongs to the group, 0 otherwise) */ -#if 0 -/* getgrouplist is a nonstandard call */ static int user_belongs_to_group(uid_t uid, gid_t gid) { struct passwd *pw=getpwuid(uid); - int found=0; - if (pw != NULL) { - int gsize=8; - int scan; - gid_t *grouplist=NULL; - do { - grouplist=realloc(grouplist, gsize*sizeof(gid_t)); - } while (grouplist != NULL && getgrouplist(pw->pw_name,pw->pw_gid,grouplist,&gsize) < 0); - if (grouplist != NULL) { - for (scan=0;scan<gsize && !found;scan++) - if (grouplist[scan]==gid) - found=1; - free(grouplist); - } - } - return found; -} -#endif -static int user_belongs_to_group(uid_t uid, gid_t gid) -{ - struct passwd *pw=getpwuid(uid); if (pw == NULL) return 0; else { @@ -259,8 +234,7 @@ /* initialize a port structure with control=fd, given data+data_len and sender * function; * and then add it to the g_fdsdata array at index i. */ -int setup_ep(int portno, int fd_ctl, - void *data, +int setup_ep(int portno, int fd_ctl, int fd_data, uid_t user, struct mod_support *modfun) { @@ -269,11 +243,9 @@ if ((portno = alloc_port(portno)) >= 0) { port=portv[portno]; - if (port->fd_data < 0 && checkport_ac(port,user)==0) { - port->fd_data=modfun->newport(fd_ctl,portno,user); + if (port->ep == NULL && checkport_ac(port,user)==0) port->curuser=user; - } - if (port->fd_data >= 0 && port->curuser == user && + if (port->curuser == user && (ep=malloc(sizeof(struct endpoint))) != NULL) { DBGOUT(DBGEPNEW,"Port %02d FD %2d", portno,fd_ctl); EVENTOUT(DBGEPNEW,portno,fd_ctl); @@ -281,7 +253,7 @@ port->sender=modfun->sender; ep->port=portno; ep->fd_ctl=fd_ctl; - ep->data=data; + ep->fd_data=fd_data; ep->descr=NULL; if(port->ep == NULL) {/* WAS INACTIVE */ register int i; @@ -308,9 +280,7 @@ return portno; } else { - if (port->fd_data < 0) - errno=EPERM; - else if (port->curuser != user) + if (port->curuser != user) errno=EADDRINUSE; else errno=ENOMEM; @@ -347,8 +317,11 @@ DBGOUT(DBGEPDEL,"Port %02d FD %2d",this->port,fd_ctl); EVENTOUT(DBGEPDEL,this->port,fd_ctl); *pep=this->next; +#ifdef VDE_PQ + packetq_delfd(this->fd_data); +#endif if (portv[this->port]->ms->delep) - portv[this->port]->ms->delep(this->fd_ctl,this->data,this->descr); + portv[this->port]->ms->delep(this->fd_ctl,this->fd_data,this->descr); free(this); return 0; } else @@ -367,12 +340,9 @@ DBGOUT(DBGPORTDEL,"%02d",portno); EVENTOUT(DBGPORTDEL,portno); hash_delete_port(portno); -#ifdef VDE_PQ - packetq_delfd(port->fd_data); -#endif - if (portv[portno]->ms->delport) + /*if (portv[portno]->ms->delport) portv[portno]->ms->delport(port->fd_data,portno); - port->fd_data=-1; + port->fd_data=-1;*/ port->ms=NULL; port->sender=NULL; port->curuser=-1; @@ -423,8 +393,8 @@ struct endpoint *ep; \ SEND_COUNTER_UPD(Port,LEN); \ 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); \ + if (Port->ms->sender(ep->fd_ctl, ep->fd_data, (PACKET), (LEN), ep->port)) \ + packetq_add(Port->ms->sender,ep->fd_ctl, ep->fd_data, (PACKET), (LEN), ep->port); \ } \ }) #else @@ -435,7 +405,7 @@ struct endpoint *ep; \ SEND_COUNTER_UPD(Port,LEN); \ for (ep=Port->ep; ep != NULL; ep=ep->next) \ - Port->ms->sender(Port->fd_data, ep->fd_ctl, (PACKET), (LEN), ep->data, ep->port); \ + Port->ms->sender(ep->fd_ctl, ep->fd_data, (PACKET), (LEN), ep->port); \ } \ }) #endif Modified: branches/rd235/vde-2/src/vde_switch/port.h =================================================================== --- branches/rd235/vde-2/src/vde_switch/port.h 2011-03-16 21:30:55 UTC (rev 478) +++ branches/rd235/vde-2/src/vde_switch/port.h 2011-03-25 18:08:57 UTC (rev 479) @@ -37,14 +37,14 @@ struct mod_support { char *modname; - int (*sender)(int fd, int fd_ctl, void *packet, int len, void *data, int port); - int (*newport)(int fd_ctl,int portno,uid_t user); - void (*delep)(int fd, void* data, void *descr); - void (*delport)(int fd,int portno); + int (*sender)(int fd_ctl, int fd_data, void *packet, int len, int port); +// int (*newport)(int fd_ctl,int portno,uid_t user); + void (*delep)(int fd_ctl, int fd_data, void *descr); +// void (*delport)(int fd,int portno); }; extern int setup_ep(int portno, int fd_ctl, - void *data, + int fd_data, uid_t user, struct mod_support *modfun); Modified: branches/rd235/vde-2/src/vde_switch/tuntap.c =================================================================== --- branches/rd235/vde-2/src/vde_switch/tuntap.c 2011-03-16 21:30:55 UTC (rev 478) +++ branches/rd235/vde-2/src/vde_switch/tuntap.c 2011-03-25 18:08:57 UTC (rev 479) @@ -52,11 +52,11 @@ struct init_tap *hinit_tap=NULL; -static int send_tap(int fd, int ctl_fd, void *packet, int len, void *unused, int port) +static int send_tap(int fd_ctl, int fd_data, void *packet, int len, int port) { int n; - n = len - write(ctl_fd, packet, len); + n = len - write(fd_ctl, packet, len); if(n){ int rv=errno; #ifndef VDE_PQ @@ -71,12 +71,6 @@ return 0; } -static void closeport(int fd, int portno) -{ - if (fd>0) - remove_fd(fd); -} - static void handle_input(unsigned char type,int fd,int revents,int *arg) { struct bipacket packet; @@ -175,6 +169,11 @@ close(fd); return(-1); } +#ifdef VDE_PQ + /* tuntap should be "fast", but if there is a packetq we can manage + a tuntap which is "not fast enough" */ + fcntl(fd, F_SETFL, O_NONBLOCK); +#endif return(fd); } #endif @@ -209,17 +208,12 @@ } #endif -static int newport(int fd, int portno, uid_t user) -{ - return fd; -} - static int newtap(char *dev) { int tap_fd; tap_fd = open_tap(dev); if (tap_fd>0) { - int portno=setup_ep(0,tap_fd,NULL,-1,&modfun); + int portno=setup_ep(0,tap_fd,tap_fd,-1,&modfun); if (portno >= 0) { setup_description(portno,tap_fd,dev); add_fd(tap_fd,tap_type,portno); @@ -243,8 +237,10 @@ } } -static void delep (int fd, void* data, void *descr) +static void delep (int fd_ctl, int fd_data, void *descr) { + if (fd_ctl>=0) + remove_fd(fd_ctl); if (descr) free(descr); } @@ -259,9 +255,7 @@ swmi.handle_input=handle_input; swmi.cleanup=cleanup; modfun.sender=send_tap; - modfun.newport=newport; modfun.delep=delep; - modfun.delport=closeport; add_swm(&swmi); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Enable your software for Intel(R) Active Management Technology to meet the growing manageability and security demands of your customers. Businesses are taking advantage of Intel(R) vPro (TM) technology - will your software be a part of the solution? Download the Intel(R) Manageability Checker today! http://p.sf.net/sfu/intel-dev2devmar _______________________________________________ vde-users mailing list vde-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vde-users