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
[email protected]
https://lists.sourceforge.net/lists/listinfo/vde-users