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