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

Reply via email to