1 /* source: xio-vsock.c */
2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
3 /* Author: Stefano Garzarella <sgarzare@redhat.com */
4 /* Published under the GNU General Public License V.2, see file COPYING */
6 /* this file contains the source for opening addresses of VSOCK socket type */
8 #include "xiosysincludes.h"
12 #include "xio-listen.h"
13 #include "xio-socket.h"
14 #include "xio-vsock.h"
16 static int xioopen_vsock_connect(int argc
, const char *argv
[], struct opt
*opts
,
17 int xioflags
, xiofile_t
*xxfd
, unsigned groups
, int abstract
,
18 int dummy2
, int dummy3
);
19 static int xioopen_vsock_listen(int argc
, const char *argv
[], struct opt
*opts
,
20 int xioflags
, xiofile_t
*xxfd
, unsigned groups
, int abstract
,
21 int dummy2
, int dummy3
);
23 const struct addrdesc addr_vsock_connect
= { "vsock-connect", 1 + XIO_RDWR
,
24 xioopen_vsock_connect
,
25 GROUP_FD
|GROUP_SOCKET
|GROUP_CHILD
|GROUP_RETRY
,
26 0, 0, 0 HELP(":<cid>:<port>") };
28 const struct addrdesc addr_vsock_listen
= { "vsock-listen", 1 + XIO_RDWR
,
30 GROUP_FD
|GROUP_SOCKET
|GROUP_LISTEN
|GROUP_CHILD
|GROUP_RETRY
,
31 0, 0, 0 HELP(":<port>") };
32 #endif /* WITH_LISTEN */
34 static int vsock_addr_init(struct sockaddr_vm
*sa
, const char *cid_str
,
35 const char *port_str
) {
38 memset(sa
, 0, sizeof(*sa
));
40 sa
->svm_family
= AF_VSOCK
;
41 ret
= sockaddr_vm_parse(sa
, cid_str
, port_str
);
48 static int vsock_init(struct opt
*opts
, struct single
*xfd
) {
50 xfd
->howtoend
= END_SHUTDOWN
;
52 if (applyopts_single(xfd
, opts
, PH_INIT
) < 0)
55 applyopts(-1, opts
, PH_INIT
);
56 applyopts(-1, opts
, PH_EARLY
);
58 xfd
->dtype
= XIODATA_STREAM
;
63 static int xioopen_vsock_connect(int argc
, const char *argv
[], struct opt
*opts
,
64 int xioflags
, xiofile_t
*xxfd
, unsigned groups
,
65 int abstract
, int dummy2
, int dummy3
) {
66 /* we expect the form :cid:port */
67 struct single
*xfd
= &xxfd
->stream
;
68 struct sockaddr_vm sa
, sa_local
;
69 socklen_t sa_len
= sizeof(sa
);
70 bool needbind
= false;
71 int socktype
= SOCK_STREAM
;
77 Error2("%s: wrong number of parameters (%d instead of 2)",
82 ret
= vsock_addr_init(&sa
, argv
[1], argv
[2]);
87 ret
= vsock_init(opts
, xfd
);
92 ret
= retropt_bind(opts
, pf
, socktype
, protocol
,
93 (struct sockaddr
*)&sa_local
, &sa_len
, 3, 0, 0);
94 if (ret
== STAT_NORETRY
)
99 ret
= xioopen_connect(xfd
, needbind
? (union sockaddr_union
*)&sa_local
: NULL
,
100 sa_len
, (struct sockaddr
*)&sa
, sizeof(sa
),
101 opts
, pf
, socktype
, protocol
, false);
105 ret
= _xio_openlate(xfd
, opts
);
113 static int xioopen_vsock_listen(int argc
, const char *argv
[], struct opt
*opts
,
114 int xioflags
, xiofile_t
*xxfd
, unsigned groups
, int abstract
,
115 int dummy2
, int dummy3
) {
116 /* we expect the form :port */
117 struct single
*xfd
= &xxfd
->stream
;
118 struct sockaddr_vm sa
, sa_bind
;
119 socklen_t sa_len
= sizeof(sa_bind
);
121 int socktype
= SOCK_STREAM
;
127 Error2("%s: wrong number of parameters (%d instead of 1)",
132 ret
= vsock_addr_init(&sa
, NULL
, argv
[1]);
137 ret
= vsock_init(opts
, xfd
);
144 if (Ioctl(xfd
->fd
, IOCTL_VM_SOCKETS_GET_LOCAL_CID
, &cid
) < 0) {
145 Warn2("ioctl(%d, IOCTL_VM_SOCKETS_GET_LOCAL_CID, ...): %s",
146 xfd
->fd
, strerror(errno
));
148 Notice1("VSOCK CID=%u", cid
);
152 opts0
= copyopts(opts
, GROUP_ALL
);
154 ret
= retropt_bind(opts
, pf
, socktype
, protocol
, (struct sockaddr
*)&sa_bind
,
156 if (ret
== STAT_NORETRY
)
159 sa
.svm_cid
= sa_bind
.svm_cid
;
161 /* this may fork() */
162 return xioopen_listen(xfd
, xioflags
, (struct sockaddr
*)&sa
, sizeof(sa
),
163 opts
, opts0
, pf
, socktype
, protocol
);
166 #endif /* WITH_LISTEN */
167 #endif /* WITH_VSOCK */