Revision: 447
          http://vde.svn.sourceforge.net/vde/?rev=447&view=rev
Author:   rd235
Date:     2010-11-20 13:58:58 +0000 (Sat, 20 Nov 2010)

Log Message:
-----------
libvdeplug: point-to-point link support

Modified Paths:
--------------
    trunk/vde-2/src/lib/Makefile.am
    trunk/vde-2/src/lib/libvdeplug.c

Modified: trunk/vde-2/src/lib/Makefile.am
===================================================================
--- trunk/vde-2/src/lib/Makefile.am     2010-11-16 18:57:03 UTC (rev 446)
+++ trunk/vde-2/src/lib/Makefile.am     2010-11-20 13:58:58 UTC (rev 447)
@@ -23,7 +23,7 @@
 libvdemgmt_la_LDFLAGS = $(AM_LDFLAGS) -version-number 0:0:1 -export-dynamic
 
 libvdeplug_la_LIBADD = $(LIBADD)
-libvdeplug_la_LDFLAGS = $(AM_LDFLAGS) -version-number 3:0:1 -export-dynamic
+libvdeplug_la_LDFLAGS = $(AM_LDFLAGS) -version-number 2:2:1 -export-dynamic
 
 libvdehist_la_LIBADD = $(LIBADD)
 libvdehist_la_LDFLAGS = $(AM_LDFLAGS) -version-number 0:0:1 -export-dynamic

Modified: trunk/vde-2/src/lib/libvdeplug.c
===================================================================
--- trunk/vde-2/src/lib/libvdeplug.c    2010-11-16 18:57:03 UTC (rev 446)
+++ trunk/vde-2/src/lib/libvdeplug.c    2010-11-20 13:58:58 UTC (rev 447)
@@ -1,6 +1,7 @@
 /*
  * libvdeplug - A library to connect to a VDE Switch.
  * Copyright (C) 2006 Renzo Davoli, University of Bologna
+ * (c) 2010 Renzo Davoli - stream + point2point
  *
  * 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
@@ -94,10 +95,12 @@
        int fdctl;
        int fddata;
        struct sockaddr_un inpath;
+       struct sockaddr_un *outpath;
 };
 
 #define SWITCH_MAGIC 0xfeedface
 #define MAXDESCR 128
+#define VDEFLAG_P2P_SOCKET 1
 
 enum request_type { REQ_NEW_CONTROL, REQ_NEW_PORT0 };
 
@@ -122,6 +125,7 @@
        char *group=NULL;
        mode_t mode=0700;
        int sockno=0;
+       int flags=0;
        int res;
        char *std_sockname=NULL;
        char *real_sockname=NULL;
@@ -132,6 +136,8 @@
                        port=open_args->port;
                        group=open_args->group;
                        mode=open_args->mode;
+                       if (port == -1)
+                               flags |= VDEFLAG_P2P_SOCKET;
                }
                else {
                        errno=EINVAL;
@@ -184,7 +190,9 @@
                        *split=0;
                        split++;
                        port=atoi(split);
-                       if (port == 0)
+                       if (*split==']')
+                               flags |= VDEFLAG_P2P_SOCKET;
+                       else if (port == 0)
                                req->type = REQ_NEW_PORT0;
                        if (*given_sockname==0)
                                given_sockname = NULL;
@@ -195,7 +203,8 @@
         * 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 && vde_realpath(given_sockname, real_sockname) == 
NULL)
+       if (given_sockname && !(flags & VDEFLAG_P2P_SOCKET) &&
+                       vde_realpath(given_sockname, real_sockname) == NULL)
                goto abort;
 
 #ifdef USE_IPN
@@ -208,7 +217,8 @@
                sockun.sun_family = AF_IPN;
        }
 #endif
-       if((conn->fddata = socket(AF_IPN_STOLEN,SOCK_RAW,IPN_ANY)) >= 0) {
+       if((flags & VDEFLAG_P2P_SOCKET) == 0 &&
+                       (conn->fddata = socket(AF_IPN_STOLEN,SOCK_RAW,IPN_ANY)) 
>= 0) {
                /* IPN_STOLEN service exists */
                sockun->sun_family = AF_IPN_STOLEN;
                if (port != 0 || req->type == REQ_NEW_PORT0)
@@ -245,6 +255,55 @@
                        close(conn->fddata);
        }
 #endif
+       /* define a female socket for point2point connection */
+       if (flags & VDEFLAG_P2P_SOCKET) {
+               struct stat sockstat;
+               if(given_sockname == NULL) {
+                       errno = EINVAL;
+                       goto abort;
+               }
+               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);
+               /* the socket already exists */
+               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;
+               memcpy(&(conn->inpath),sockun,sizeof(conn->inpath));
+               conn->outpath = calloc(1,sizeof(struct sockaddr_un));
+               if (conn->outpath==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;
+               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);
+               goto cleanup;
+       }
        if((conn->fdctl = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
                goto abort;
        if((conn->fddata = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
@@ -276,8 +335,46 @@
                }
        }
 
-       if (res != 0)
-               goto abort;
+       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;
+               memcpy(&(conn->inpath),sockun,sizeof(conn->inpath));
+               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;
@@ -376,6 +473,8 @@
                                close(conn->fddata);
                        if (*(conn->inpath.sun_path))
                                unlink(conn->inpath.sun_path);
+                       if (conn->outpath != NULL)
+                               free(conn->outpath);
                        free(conn);
                }
                conn = NULL;
@@ -402,9 +501,13 @@
 
 ssize_t vde_send(VDECONN *conn,const void *buf,size_t len,int flags)
 {
-       if (__builtin_expect(conn!=0,1)) 
-               return send(conn->fddata,buf,len,0);
-       else {
+       if (__builtin_expect(conn!=0,1)) {
+               if (__builtin_expect(conn->outpath == NULL,1))
+                       return send(conn->fddata,buf,len,0);
+               else 
+                       return sendto(conn->fddata,buf,len,0,
+                               (struct sockaddr 
*)conn->outpath,sizeof(conn->inpath));
+       } else {
                errno=EBADF;
                return -1;
        }
@@ -435,6 +538,8 @@
        if (__builtin_expect(conn!=0,1)) {
                if (*(conn->inpath.sun_path))
                        unlink(conn->inpath.sun_path);
+               if (conn->outpath != NULL)
+                       free(conn->outpath);
                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.

------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1,  ECMAScript5, and DOM L2 & L3.
Spend less time writing and  rewriting code and more time creating great
experiences on the web. Be a part of the beta today
http://p.sf.net/sfu/msIE9-sfdev2dev
_______________________________________________
vde-users mailing list
vde-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vde-users

Reply via email to