Oh yes. Use goto please and show up that it is not the evil if well used. Once I had a last blood fight with a teacher (teach-automata in that case) about goto and while(true) cycles. I lost.
Simone 2011/4/29 <rd...@users.sourceforge.net>: > Revision: 494 > http://vde.svn.sourceforge.net/vde/?rev=494&view=rev > Author: rd235 > Date: 2011-04-29 16:42:39 +0000 (Fri, 29 Apr 2011) > > Log Message: > ----------- > libvdeplug: added UDP connection > > Modified Paths: > -------------- > branches/rd235/vde-2/src/lib/libvdeplug.c > > Modified: branches/rd235/vde-2/src/lib/libvdeplug.c > =================================================================== > --- branches/rd235/vde-2/src/lib/libvdeplug.c 2011-04-23 14:25:39 UTC (rev > 493) > +++ branches/rd235/vde-2/src/lib/libvdeplug.c 2011-04-29 16:42:39 UTC (rev > 494) > @@ -2,6 +2,7 @@ > * libvdeplug - A library to connect to a VDE Switch. > * Copyright (C) 2006 Renzo Davoli, University of Bologna > * (c) 2010 Renzo Davoli - stream + point2point > + * (c) 2011 Renzo Davoli - udpconnect > * > * This library is free software; you can redistribute it and/or modify it > * under the terms of the GNU Lesser General Public License as published by > @@ -32,6 +33,8 @@ > #include <sys/uio.h> > #include <unistd.h> > #include <string.h> > +#include <netdb.h> > +#include <netinet/in.h> > > #include <config.h> > #include <vde.h> > @@ -95,13 +98,16 @@ > struct vdeconn { > int fdctl; > int fddata; > - struct sockaddr_un inpath; > - struct sockaddr_un *outpath; > + char *inpath; > + size_t outlen; > + struct sockaddr *outsock; > }; > > #define SWITCH_MAGIC 0xfeedface > #define MAXDESCR 128 > #define VDEFLAG_P2P_SOCKET 1 > +#define VDEFLAG_UDP_SOCKET 2 > +#define VDEFLAG_P2P (VDEFLAG_P2P_SOCKET | VDEFLAG_UDP_SOCKET) > > enum request_type { REQ_NEW_CONTROL, REQ_NEW_PORT0 }; > > @@ -118,10 +124,8 @@ > { > struct vdeconn *conn=NULL; > struct passwd *callerpwd; > - struct request_v3 *req=NULL; > + struct request_v3 req; > int pid = getpid(); > - struct sockaddr_un *sockun=NULL; > - struct sockaddr_un *dataout=NULL; > int port=0; > char *group=NULL; > mode_t mode=0700; > @@ -148,18 +152,7 @@ > } > } > > - if ((req=(struct request_v3 *)calloc(1, sizeof(struct > request_v3)))==NULL) { > - errno=ENOMEM; > - goto abort; > - } > - if ((sockun=(struct sockaddr_un *)calloc(1, sizeof(struct > sockaddr_un)))==NULL) { > - errno=ENOMEM; > - goto abort; > - } > - if ((dataout=(struct sockaddr_un *)calloc(1, sizeof(struct > sockaddr_un)))==NULL) { > - errno=ENOMEM; > - goto abort; > - } > + memset(&req, 0, sizeof(req)); > if ((std_sockname=(char *)calloc(PATH_MAX,sizeof(char)))==NULL) { > errno=ENOMEM; > goto abort; > @@ -177,7 +170,7 @@ > conn->fdctl=conn->fddata=-1; > //get the login name > callerpwd=getpwuid(getuid()); > - req->type = REQ_NEW_CONTROL; > + req.type = REQ_NEW_CONTROL; > if (given_sockname == NULL || *given_sockname == '\0') { > char *homedir = getenv("HOME"); > given_sockname = NULL; > @@ -189,14 +182,17 @@ > } > } else { > char *split; > - if(given_sockname[strlen(given_sockname)-1] == ']' && > (split=rindex(given_sockname,'[')) != NULL) { > + if((split = strstr(given_sockname,"->")) != NULL && > rindex(split,':') != NULL) > + flags |= VDEFLAG_UDP_SOCKET; > + else if(given_sockname[strlen(given_sockname)-1] == ']' > + && (split=rindex(given_sockname,'[')) != > NULL) { > *split=0; > split++; > port=atoi(split); > if (*split==']') > flags |= VDEFLAG_P2P_SOCKET; > else if (port == 0) > - req->type = REQ_NEW_PORT0; > + req.type = REQ_NEW_PORT0; > if (*given_sockname==0) > given_sockname = NULL; > } > @@ -206,7 +202,7 @@ > * switch (we don't know its cwd) for the data socket. Appending > * given_sockname to getcwd() would be enough, but we could end up > with a > * name longer than PATH_MAX that couldn't be used as sun_path. */ > - if (given_sockname && !(flags & VDEFLAG_P2P_SOCKET) && > + if (given_sockname && !(flags & VDEFLAG_P2P) && > vde_realpath(given_sockname, real_sockname) == NULL) > goto abort; > > @@ -220,17 +216,19 @@ > sockun.sun_family = AF_IPN; > } > #endif > - if((flags & VDEFLAG_P2P_SOCKET) == 0 && > + if((flags & VDEFLAG_P2P) == 0 && > (conn->fddata = > socket(AF_IPN_STOLEN,SOCK_RAW,IPN_ANY)) >= 0) { > + struct sockaddr_un sockun; > + memset(&sockun, 0, sizeof(sockun)); > /* IPN_STOLEN service exists */ > - sockun->sun_family = AF_IPN_STOLEN; > - if (port != 0 || req->type == REQ_NEW_PORT0) > + sockun.sun_family = AF_IPN_STOLEN; > + if (port != 0 || req.type == REQ_NEW_PORT0) > > setsockopt(conn->fddata,0,IPN_SO_PORT,&port,sizeof(port)); > /* If we're given a sockname, just try it */ > if (given_sockname) > { > - snprintf(sockun->sun_path, sizeof(sockun->sun_path), > "%s", sockname); > - res = connect(conn->fddata, (struct sockaddr *) > sockun, sizeof(*sockun)); > + snprintf(sockun.sun_path, sizeof(sockun.sun_path), > "%s", sockname); > + res = connect(conn->fddata, (struct sockaddr *) > &sockun, sizeof(sockun)); > } > /* Else try all the fallback socknames, one by one */ > else > @@ -238,36 +236,106 @@ > int i; > for (i = 0, res = -1; fallback_sockname[i] && (res != > 0); i++) > { > - snprintf(sockun->sun_path, > sizeof(sockun->sun_path), "%s", fallback_sockname[i]); > - res = connect(conn->fddata, (struct sockaddr > *) sockun, sizeof(*sockun)); > + snprintf(sockun.sun_path, > sizeof(sockun.sun_path), "%s", fallback_sockname[i]); > + res = connect(conn->fddata, (struct sockaddr > *) &sockun, sizeof(sockun)); > } > } > > /* If one of the connect succeeded, we're done */ > if (res == 0) > { > - int descrlen=snprintf(req->description,MAXDESCR,"%s > user=%s PID=%d", > + int descrlen=snprintf(req.description,MAXDESCR,"%s > user=%s PID=%d", > descr,(callerpwd != > NULL)?callerpwd->pw_name:"??", > pid); > if (ssh_client) { > char *endofip=strchr(ssh_client,' '); > if (endofip) *endofip=0; > - > snprintf(req->description+descrlen,MAXDESCR-descrlen, > + > snprintf(req.description+descrlen,MAXDESCR-descrlen, > " SSH=%s", ssh_client); > if (endofip) *endofip=' '; > } > - > setsockopt(conn->fddata,0,IPN_SO_DESCR,req->description, > - strlen(req->description+1)); > - *(conn->inpath.sun_path)=0; /*null string, do not > delete "return path"*/ > + > setsockopt(conn->fddata,0,IPN_SO_DESCR,req.description, > + strlen(req.description+1)); > conn->fdctl=-1; > goto cleanup; > } else > close(conn->fddata); > } > #endif > + /* UDP connection */ > + if (flags & VDEFLAG_UDP_SOCKET) { > + struct addrinfo hints; > + struct addrinfo *result,*rp; > + int s; > + char *dst=strstr(given_sockname,"->"); > + char *src=given_sockname; > + char *srcport; > + char *dstport; > + memset(&hints,0,sizeof(hints)); > + hints.ai_socktype=SOCK_DGRAM; > + *dst=0; > + dst+=2; > + dstport=rindex(dst,':'); > + if (dstport==NULL) { > + errno=EINVAL; > + goto abort; > + } > + *dstport=0; > + dstport++; > + srcport=rindex(src,':'); > + if (srcport==NULL) { > + srcport=src; > + src=NULL; > + } > + //fprintf(stderr,"UDP!%s:%s -> %s:%s > \n",src,srcport,dst,dstport); > + hints.ai_flags = AI_PASSIVE; > + s = getaddrinfo(src, srcport, &hints, &result); > + > + if (s != 0) { > + errno=ECONNABORTED; > + goto abort; > + } > + > + for (rp = result; rp != NULL; rp = rp->ai_next) { > + conn->fddata = socket(rp->ai_family, rp->ai_socktype, > rp->ai_protocol); > + if (conn->fddata == -1) > + continue; > + > + if (bind(conn->fddata, rp->ai_addr, rp->ai_addrlen) > == 0) > + break; /* Success */ > + > + close(conn->fddata); > + } > + > + if (rp == NULL) { > + errno=ECONNABORTED; > + goto abort; > + } > + > + freeaddrinfo(result); > + hints.ai_flags = 0; > + > + s = getaddrinfo(dst, dstport, &hints, &result); > + > + if (s != 0) { > + errno=ECONNABORTED; > + goto abort; > + } > + /* for now it takes the first */ > + conn->outlen = result->ai_addrlen; > + conn->outsock = malloc(result->ai_addrlen); > + memcpy(conn->outsock, result->ai_addr, result->ai_addrlen); > + > + freeaddrinfo(result); > + > + goto cleanup; > + } > /* define a female socket for point2point connection */ > if (flags & VDEFLAG_P2P_SOCKET) { > struct stat sockstat; > + struct sockaddr_un sockun; > + struct sockaddr_un *sockout; > + memset(&sockun, 0, sizeof(sockun)); > if(given_sockname == NULL) { > errno = EINVAL; > goto abort; > @@ -275,33 +343,32 @@ > strcpy(sockname,given_sockname); /* XXX canonicalize should be > better */ > if((conn->fddata = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) > goto abort; > - sockun->sun_family = AF_UNIX; > - memset(sockun->sun_path,0,sizeof(sockun->sun_path)); > - snprintf(sockun->sun_path, sizeof(sockun->sun_path)-1, "%s", > sockname); > + sockun.sun_family = AF_UNIX; > + memset(sockun.sun_path,0,sizeof(sockun.sun_path)); > + snprintf(sockun.sun_path, sizeof(sockun.sun_path)-1, "%s", > sockname); > /* the socket already exists */ > - if(stat(sockun->sun_path,&sockstat) == 0) { > + if(stat(sockun.sun_path,&sockstat) == 0) { > if (S_ISSOCK(sockstat.st_mode)) { > /* the socket is already in use */ > - res = connect(conn->fddata, (struct sockaddr > *) sockun, sizeof(*sockun)); > + res = connect(conn->fddata, (struct sockaddr > *) &sockun, sizeof(sockun)); > if (res >= 0) { > errno = EADDRINUSE; > goto abort; > } > if (errno == ECONNREFUSED) > - unlink(sockun->sun_path); > + unlink(sockun.sun_path); > } > } > - res = bind(conn->fddata, (struct sockaddr *) sockun, > sizeof(*sockun)); > + res = bind(conn->fddata, (struct sockaddr *) &sockun, > sizeof(sockun)); > if (res < 0) > goto abort; > - memcpy(&(conn->inpath),sockun,sizeof(conn->inpath)); > - conn->outpath = calloc(1,sizeof(struct sockaddr_un)); > - if (conn->outpath==NULL) > + conn->inpath=strdup(sockun.sun_path); > + conn->outlen = sizeof(struct sockaddr_un); > + conn->outsock = (struct sockaddr *) (sockout = > calloc(1,sizeof(struct sockaddr_un))); > + if (conn->outsock ==NULL) > goto abort; > - conn->outpath->sun_family = AF_UNIX; > - snprintf(conn->outpath->sun_path, sizeof(sockun->sun_path), > "%s+", sockname); > - if (!conn->outpath) > - goto abort; > + sockout->sun_family = AF_UNIX; > + snprintf(sockout->sun_path, sizeof(sockun.sun_path), "%s+", > sockname); > if (group) { > struct group *gs; > gid_t gid; > @@ -309,182 +376,190 @@ > gid=atoi(group); > else > gid=gs->gr_gid; > - chown(conn->inpath.sun_path,-1,gid); > + chown(sockun.sun_path,-1,gid); > } > - chmod(conn->inpath.sun_path,mode); > + chmod(sockun.sun_path,mode); > goto cleanup; > - } > - if((conn->fdctl = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) > - goto abort; > - if((conn->fddata = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) > - goto abort; > - sockun->sun_family = AF_UNIX; > + } else { > + struct sockaddr_un sockun; > + struct sockaddr_un dataout; > + memset(&sockun, 0, sizeof(sockun)); > + memset(&dataout, 0, sizeof(dataout)); > > - /* If we're given a sockname, just try it (remember: sockname is the > - * canonicalized version of given_sockname - though we don't strictly > need > - * the canonicalized versiono here). sockname should be the name of a > - * *directory* which contains the control socket, named ctl. Older > - * versions of VDE used a socket instead of a directory (so an > additional > - * attempt with %s instead of %s/ctl could be made), but they should > - * really not be used anymore. */ > - if (given_sockname) > - { > - snprintf(sockun->sun_path, sizeof(sockun->sun_path), > "%s/ctl", sockname); > - res = connect(conn->fdctl, (struct sockaddr *) sockun, > sizeof(*sockun)); > - } > - /* Else try all the fallback socknames, one by one */ > - else > - { > - int i; > - for (i = 0, res = -1; fallback_sockname[i] && (res != 0); i++) > + /* connection to a vde_switch */ > + if((conn->fdctl = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) > + goto abort; > + if((conn->fddata = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) > + goto abort; > + sockun.sun_family = AF_UNIX; > + > + /* If we're given a sockname, just try it (remember: sockname > is the > + * canonicalized version of given_sockname - though we don't > strictly need > + * the canonicalized versiono here). sockname should be the > name of a > + * *directory* which contains the control socket, named ctl. > Older > + * versions of VDE used a socket instead of a directory (so > an additional > + * attempt with %s instead of %s/ctl could be made), but they > should > + * really not be used anymore. */ > + if (given_sockname) > { > - /* Remember sockname for the data socket directory */ > - sockname = fallback_sockname[i]; > - snprintf(sockun->sun_path, sizeof(sockun->sun_path), > "%s", sockname); > - res = connect(conn->fdctl, (struct sockaddr *) > sockun, sizeof(*sockun)); > + snprintf(sockun.sun_path, sizeof(sockun.sun_path), > "%s/ctl", sockname); > + res = connect(conn->fdctl, (struct sockaddr *) > &sockun, sizeof(sockun)); > } > - } > + /* Else try all the fallback socknames, one by one */ > + else > + { > + int i; > + for (i = 0, res = -1; fallback_sockname[i] && (res != > 0); i++) > + { > + /* Remember sockname for the data socket > directory */ > + sockname = fallback_sockname[i]; > + snprintf(sockun.sun_path, > sizeof(sockun.sun_path), "%s", sockname); > + res = connect(conn->fdctl, (struct sockaddr > *) &sockun, sizeof(sockun)); > + } > + } > > - if (res != 0) { > - struct stat sockstat; > - /* define a male plug for point2point connection */ > - if (!given_sockname) > - goto abort; > - snprintf(sockun->sun_path, sizeof(sockun->sun_path), "%s", > sockname); > - res = connect(conn->fddata, (struct sockaddr *) sockun, > sizeof(*sockun)); > + if (res != 0) { > + struct stat sockstat; > + /* define a male plug for point2point connection */ > + if (!given_sockname) > + goto abort; > + snprintf(sockun.sun_path, sizeof(sockun.sun_path), > "%s", sockname); > + res = connect(conn->fddata, (struct sockaddr *) > &sockun, sizeof(sockun)); > + if (res < 0) > + goto abort; > + snprintf(sockun.sun_path, sizeof(sockun.sun_path), > "%s+", sockname); > + if(stat(sockun.sun_path,&sockstat) == 0) { > + if (S_ISSOCK(sockstat.st_mode)) { > + /* the socket is already in use */ > + res = connect(conn->fddata, (struct > sockaddr *) &sockun, sizeof(sockun)); > + if (res >= 0) { > + errno = EADDRINUSE; > + goto abort; > + } > + if (errno == ECONNREFUSED) > + unlink(sockun.sun_path); > + } > + } > + res = bind(conn->fddata, (struct sockaddr *) &sockun, > sizeof(sockun)); > + if (res < 0) > + goto abort; > + conn->inpath=strdup(sockun.sun_path); > + if (group) { > + struct group *gs; > + gid_t gid; > + if ((gs=getgrnam(group)) == NULL) > + gid=atoi(group); > + else > + gid=gs->gr_gid; > + chown(sockun.sun_path,-1,gid); > + } > + chmod(sockun.sun_path,mode); > + close(conn->fdctl); > + conn->fdctl=-1; > + goto cleanup; > + } > + > + req.magic=SWITCH_MAGIC; > + req.version=3; > + req.type=req.type+(port << 8); > + req.sock.sun_family=AF_UNIX; > + > + /* First choice, store the return socket from the switch in > the control > + * dir. We assume that given_sockname (hence sockname) is a > directory. > + * Should be a safe assumption unless someone modifies the > previous group > + * of connect() attempts (see the comments above for more > information). */ > + memset(req.sock.sun_path, 0, sizeof(req.sock.sun_path)); > + do > + { > + /* Here sockname is the last successful one in the > previous step. */ > + sprintf(req.sock.sun_path, "%s/.%05d-%05d", sockname, > pid, sockno++); > + res=bind(conn->fddata, (struct sockaddr *) &req.sock, > sizeof (req.sock)); > + } > + while (res < 0 && errno == EADDRINUSE); > + > + /* It didn't work. So we cycle on the fallback directories > until we find a > + * suitable one (or the list ends). */ > if (res < 0) > - goto abort; > - snprintf(sockun->sun_path, sizeof(sockun->sun_path), "%s+", > sockname); > - if(stat(sockun->sun_path,&sockstat) == 0) { > - if (S_ISSOCK(sockstat.st_mode)) { > - /* the socket is already in use */ > - res = connect(conn->fddata, (struct sockaddr > *) sockun, sizeof(*sockun)); > - if (res >= 0) { > - errno = EADDRINUSE; > - goto abort; > + { > + int i; > + for (i = 0, res = -1; fallback_dirname[i] && (res != > 0); i++) > + { > + memset(req.sock.sun_path, 0, > sizeof(req.sock.sun_path)); > + do > + { > + sprintf(req.sock.sun_path, > "%s/vde.%05d-%05d", fallback_dirname[i], pid, sockno++); > + res = bind(conn->fddata, (struct > sockaddr *) &req.sock, sizeof (req.sock)); > } > - if (errno == ECONNREFUSED) > - unlink(sockun->sun_path); > + while (res < 0 && errno == EADDRINUSE); > } > } > - res = bind(conn->fddata, (struct sockaddr *) sockun, > sizeof(*sockun)); > + > + /* Nothing worked, so cleanup and return with an error. */ > if (res < 0) > goto abort; > - memcpy(&(conn->inpath),sockun,sizeof(conn->inpath)); > - if (group) { > + > + conn->inpath=strdup(req.sock.sun_path); > + > + if (group) { > struct group *gs; > gid_t gid; > if ((gs=getgrnam(group)) == NULL) > gid=atoi(group); > else > gid=gs->gr_gid; > - chown(conn->inpath.sun_path,-1,gid); > - } > - chmod(conn->inpath.sun_path,mode); > - close(conn->fdctl); > - conn->fdctl=-1; > - goto cleanup; > - } > - > - req->magic=SWITCH_MAGIC; > - req->version=3; > - req->type=req->type+(port << 8); > - req->sock.sun_family=AF_UNIX; > - > - /* First choice, store the return socket from the switch in the > control > - * dir. We assume that given_sockname (hence sockname) is a directory. > - * Should be a safe assumption unless someone modifies the previous > group > - * of connect() attempts (see the comments above for more > information). */ > - memset(req->sock.sun_path, 0, sizeof(req->sock.sun_path)); > - do > - { > - /* Here sockname is the last successful one in the previous > step. */ > - sprintf(req->sock.sun_path, "%s/.%05d-%05d", sockname, pid, > sockno++); > - res=bind(conn->fddata, (struct sockaddr *) &req->sock, sizeof > (req->sock)); > - } > - while (res < 0 && errno == EADDRINUSE); > - > - /* It didn't work. So we cycle on the fallback directories until we > find a > - * suitable one (or the list ends). */ > - if (res < 0) > - { > - int i; > - for (i = 0, res = -1; fallback_dirname[i] && (res != 0); i++) > - { > - memset(req->sock.sun_path, 0, > sizeof(req->sock.sun_path)); > - do > - { > - sprintf(req->sock.sun_path, > "%s/vde.%05d-%05d", fallback_dirname[i], pid, sockno++); > - res = bind(conn->fddata, (struct sockaddr *) > &req->sock, sizeof (req->sock)); > - } > - while (res < 0 && errno == EADDRINUSE); > - } > - } > - > - /* Nothing worked, so cleanup and return with an error. */ > - if (res < 0) > - goto abort; > - > - memcpy(&(conn->inpath),&req->sock,sizeof(req->sock)); > - if (group) { > - struct group *gs; > - gid_t gid; > - if ((gs=getgrnam(group)) == NULL) > - gid=atoi(group); > - else > - gid=gs->gr_gid; > - chown(conn->inpath.sun_path,-1,gid); > - } else { > - /* when group is not defined, set permission for the reverse > channel */ > - struct stat ctlstat; > - /* if no permission gets "voluntarily" granted to the socket > */ > - if ((mode & 077) == 0) { > - if (stat(sockun->sun_path, &ctlstat) == 0) { > - /* if the switch is owned by root or by the > same user it should > - work 0700 */ > - if (ctlstat.st_uid != 0 && ctlstat.st_uid != > geteuid()) { > - /* try to change the group ownership > to the same of the switch */ > - /* this call succeeds if the vde user > and the owner of the switch > - belong to the group */ > - if > (chown(conn->inpath.sun_path,-1,ctlstat.st_gid) == 0) > - mode |= 070; > - else > - mode |= 077; > + chown(req.sock.sun_path,-1,gid); > + } else { > + /* when group is not defined, set permission for the > reverse channel */ > + struct stat ctlstat; > + /* if no permission gets "voluntarily" granted to the > socket */ > + if ((mode & 077) == 0) { > + if (stat(sockun.sun_path, &ctlstat) == 0) { > + /* if the switch is owned by root or > by the same user it should > + work 0700 */ > + if (ctlstat.st_uid != 0 && > ctlstat.st_uid != geteuid()) { > + /* try to change the group > ownership to the same of the switch */ > + /* this call succeeds if the > vde user and the owner of the switch > + belong to the group > */ > + if > (chown(req.sock.sun_path,-1,ctlstat.st_gid) == 0) > + mode |= 070; > + else > + mode |= 077; > + } > } > } > } > - } > - chmod(conn->inpath.sun_path,mode); > + chmod(req.sock.sun_path,mode); > > #ifdef DESCR_INCLUDE_SOCK > - descrlen=snprintf(req->description,MAXDESCR,"%s user=%s PID=%d > SOCK=%s", > - descr,(callerpwd != NULL)?callerpwd->pw_name:"??", > - pid,req->sock.sun_path); > + descrlen=snprintf(req.description,MAXDESCR,"%s user=%s PID=%d > SOCK=%s", > + descr,(callerpwd != > NULL)?callerpwd->pw_name:"??", > + pid,req.sock.sun_path); > #else > - descrlen=snprintf(req->description,MAXDESCR,"%s user=%s PID=%d", > - descr,(callerpwd != NULL)?callerpwd->pw_name:"??", > pid); > + descrlen=snprintf(req.description,MAXDESCR,"%s user=%s > PID=%d", > + descr,(callerpwd != > NULL)?callerpwd->pw_name:"??", pid); > #endif > > - if (ssh_client) { > - char *endofip=strchr(ssh_client,' '); > - if (endofip) *endofip=0; > - snprintf(req->description+descrlen,MAXDESCR-descrlen," > SSH=%s", ssh_client); > - if (endofip) *endofip=' '; > - } > + if (ssh_client) { > + char *endofip=strchr(ssh_client,' '); > + if (endofip) *endofip=0; > + snprintf(req.description+descrlen,MAXDESCR-descrlen," > SSH=%s", ssh_client); > + if (endofip) *endofip=' '; > + } > > > - if > (send(conn->fdctl,req,sizeof(*req)-MAXDESCR+strlen(req->description),0)<0) > - goto abort; > + if > (send(conn->fdctl,&req,sizeof(req)-MAXDESCR+strlen(req.description),0)<0) > + goto abort; > > - if (recv(conn->fdctl,dataout,sizeof(struct sockaddr_un),0)<0) > - goto abort; > + if (recv(conn->fdctl,&dataout,sizeof(struct sockaddr_un),0)<0) > + goto abort; > > - if (connect(conn->fddata,(struct sockaddr *)dataout,sizeof(struct > sockaddr_un))<0) > - goto abort; > + if (connect(conn->fddata,(struct sockaddr > *)&dataout,sizeof(struct sockaddr_un))<0) > + goto abort; > > - chmod(dataout->sun_path,mode); > + chmod(dataout.sun_path,mode); > > - goto cleanup; > + goto cleanup; > + } > > abort: > { > @@ -494,19 +569,16 @@ > close(conn->fdctl); > if (conn->fddata >= 0) > close(conn->fddata); > - if (*(conn->inpath.sun_path)) > - unlink(conn->inpath.sun_path); > - if (conn->outpath != NULL) > - free(conn->outpath); > + if (conn->inpath != NULL) > + unlink(conn->inpath); > + if (conn->outsock != NULL) > + free(conn->outsock); > free(conn); > } > conn = NULL; > errno=err; > } > cleanup: > - if (req) free(req); > - if (sockun) free(sockun); > - if (dataout) free(dataout); > if (std_sockname) free(std_sockname); > if (real_sockname) free(real_sockname); > return conn; > @@ -520,7 +592,7 @@ > if (__builtin_expect(((retval=recv(conn->fddata,buf,len,0)) > > 0), 1)) > return retval; > else { > - if (retval == 0 && conn->outpath != NULL) { > + if (retval == 0 && conn->outsock != NULL) { > static struct sockaddr unspec={AF_UNSPEC}; > connect(conn->fddata,&unspec,sizeof(unspec)); > } > @@ -546,12 +618,12 @@ > #ifdef CONNECTED_P2P > if (__builtin_expect(conn!=0,1)) { > ssize_t retval; > - if (__builtin_expect(((retval=send(conn->fddata,buf,len,0)) > >= 0),1)) > + if (__builtin_expect(((retval=send(conn->fddata,buf,len,0)) > >= 0),1)) > return retval; > else { > - if (__builtin_expect(errno == ENOTCONN,0)) { > - if (__builtin_expect(conn->outpath != > NULL,1)) { > - connect(conn->fddata, (struct > sockaddr *)conn->outpath,sizeof(conn->inpath)); > + if (__builtin_expect(errno == ENOTCONN || errno == > EDESTADDRREQ,0)) { > + if (__builtin_expect(conn->outsock != > NULL,1)) { > + connect(conn->fddata, > conn->outsock,conn->outlen); > return send(conn->fddata,buf,len,0); > } else > return retval; > @@ -564,11 +636,11 @@ > } > #else > if (__builtin_expect(conn!=0,1)) { > - if (__builtin_expect(conn->outpath == NULL,1)) > + if (__builtin_expect(conn->outsock == NULL,1)) > return send(conn->fddata,buf,len,0); > else > return sendto(conn->fddata,buf,len,0, > - (struct sockaddr > *)conn->outpath,sizeof(conn->inpath)); > + conn->outsock,conn->outlen); > } else { > errno=EBADF; > return -1; > @@ -602,10 +674,10 @@ > #ifdef CONNECTED_P2P > send(conn->fddata,NULL,0,0); > #endif > - if (*(conn->inpath.sun_path)) > - unlink(conn->inpath.sun_path); > - if (conn->outpath != NULL) > - free(conn->outpath); > + if (conn->inpath != NULL) > + unlink(conn->inpath); > + if (conn->outsock != NULL) > + free(conn->outsock); > close(conn->fddata); > close(conn->fdctl); > free(conn); > > > This was sent by the SourceForge.net collaborative development platform, the > world's largest Open Source development site. > > ------------------------------------------------------------------------------ > WhatsUp Gold - Download Free Network Management Software > The most intuitive, comprehensive, and cost-effective network > management toolset available today. Delivers lowest initial > acquisition cost and overall TCO of any competing solution. > http://p.sf.net/sfu/whatsupgold-sd > _______________________________________________ > vde-users mailing list > vde-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/vde-users > ------------------------------------------------------------------------------ WhatsUp Gold - Download Free Network Management Software The most intuitive, comprehensive, and cost-effective network management toolset available today. Delivers lowest initial acquisition cost and overall TCO of any competing solution. http://p.sf.net/sfu/whatsupgold-sd _______________________________________________ vde-users mailing list vde-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vde-users