aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2009-09-10 10:58:40 +0200
committerAnthony Liguori <aliguori@us.ibm.com>2009-09-11 10:19:48 -0500
commitf4c94c7c51f6ede5c33ab5879c6013b64ba2df82 (patch)
tree17abf2f1bab6495c13fe56d5cca2df8217e9ec43
parent108af7b957371423187b1498729bd6a467aae5ef (diff)
sockets: add inet_connect_opts
Add inet_connect_opts(). Does the same as inet_connect(), but uses QemuOpts. inet_connect() is a compatibility wrapper for inet_connect_opts() now and should go away some day. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r--qemu-sockets.c129
-rw-r--r--qemu_socket.h1
2 files changed, 97 insertions, 33 deletions
diff --git a/qemu-sockets.c b/qemu-sockets.c
index 0d0ce44246..65db94e864 100644
--- a/qemu-sockets.c
+++ b/qemu-sockets.c
@@ -37,6 +37,21 @@ QemuOptsList dummy_opts = {
{
.name = "path",
.type = QEMU_OPT_STRING,
+ },{
+ .name = "host",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "port",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "to",
+ .type = QEMU_OPT_NUMBER,
+ },{
+ .name = "ipv4",
+ .type = QEMU_OPT_BOOL,
+ },{
+ .name = "ipv6",
+ .type = QEMU_OPT_BOOL,
},
{ /* end if list */ }
},
@@ -237,11 +252,11 @@ listen:
return slisten;
}
-int inet_connect(const char *str, int socktype)
+int inet_connect_opts(QemuOpts *opts)
{
struct addrinfo ai,*res,*e;
- char addr[64];
- char port[33];
+ const char *addr;
+ const char *port;
char uaddr[INET6_ADDRSTRLEN+1];
char uport[33];
int sock,rc;
@@ -249,44 +264,24 @@ int inet_connect(const char *str, int socktype)
memset(&ai,0, sizeof(ai));
ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
ai.ai_family = PF_UNSPEC;
- ai.ai_socktype = socktype;
+ ai.ai_socktype = SOCK_STREAM;
- /* parse address */
- if (str[0] == '[') {
- /* IPv6 addr */
- if (2 != sscanf(str,"[%64[^]]]:%32[^,]",addr,port)) {
- fprintf(stderr, "%s: ipv6 parse error (%s)\n",
- __FUNCTION__, str);
- return -1;
- }
- ai.ai_family = PF_INET6;
- } else if (qemu_isdigit(str[0])) {
- /* IPv4 addr */
- if (2 != sscanf(str,"%64[0-9.]:%32[^,]",addr,port)) {
- fprintf(stderr, "%s: ipv4 parse error (%s)\n",
- __FUNCTION__, str);
- return -1;
- }
- ai.ai_family = PF_INET;
- } else {
- /* hostname */
- if (2 != sscanf(str,"%64[^:]:%32[^,]",addr,port)) {
- fprintf(stderr, "%s: hostname parse error (%s)\n",
- __FUNCTION__, str);
- return -1;
- }
+ addr = qemu_opt_get(opts, "host");
+ port = qemu_opt_get(opts, "port");
+ if (addr == NULL || port == NULL) {
+ fprintf(stderr, "inet_connect: host and/or port not specified\n");
+ return -1;
}
- /* parse options */
- if (strstr(str, ",ipv4"))
+ if (qemu_opt_get_bool(opts, "ipv4", 0))
ai.ai_family = PF_INET;
- if (strstr(str, ",ipv6"))
+ if (qemu_opt_get_bool(opts, "ipv6", 0))
ai.ai_family = PF_INET6;
/* lookup */
if (0 != (rc = getaddrinfo(addr, port, &ai, &res))) {
- fprintf(stderr,"getaddrinfo(%s,%s): %s\n", gai_strerror(rc),
- addr, port);
+ fprintf(stderr,"getaddrinfo(%s,%s): %s\n", addr, port,
+ gai_strerror(rc));
return -1;
}
if (sockets_debug)
@@ -327,6 +322,74 @@ int inet_connect(const char *str, int socktype)
return -1;
}
+/* compatibility wrapper */
+static int inet_parse(QemuOpts *opts, const char *str)
+{
+ const char *optstr, *h;
+ char addr[64];
+ char port[33];
+ int pos;
+
+ /* parse address */
+ if (str[0] == ':') {
+ /* no host given */
+ addr[0] = '\0';
+ if (1 != sscanf(str,":%32[^,]%n",port,&pos)) {
+ fprintf(stderr, "%s: portonly parse error (%s)\n",
+ __FUNCTION__, str);
+ return -1;
+ }
+ } else if (str[0] == '[') {
+ /* IPv6 addr */
+ if (2 != sscanf(str,"[%64[^]]]:%32[^,]%n",addr,port,&pos)) {
+ fprintf(stderr, "%s: ipv6 parse error (%s)\n",
+ __FUNCTION__, str);
+ return -1;
+ }
+ qemu_opt_set(opts, "ipv6", "yes");
+ } else if (qemu_isdigit(str[0])) {
+ /* IPv4 addr */
+ if (2 != sscanf(str,"%64[0-9.]:%32[^,]%n",addr,port,&pos)) {
+ fprintf(stderr, "%s: ipv4 parse error (%s)\n",
+ __FUNCTION__, str);
+ return -1;
+ }
+ qemu_opt_set(opts, "ipv4", "yes");
+ } else {
+ /* hostname */
+ if (2 != sscanf(str,"%64[^:]:%32[^,]%n",addr,port,&pos)) {
+ fprintf(stderr, "%s: hostname parse error (%s)\n",
+ __FUNCTION__, str);
+ return -1;
+ }
+ }
+ qemu_opt_set(opts, "host", addr);
+ qemu_opt_set(opts, "port", port);
+
+ /* parse options */
+ optstr = str + pos;
+ h = strstr(optstr, ",to=");
+ if (h)
+ qemu_opt_set(opts, "to", h+4);
+ if (strstr(optstr, ",ipv4"))
+ qemu_opt_set(opts, "ipv4", "yes");
+ if (strstr(optstr, ",ipv6"))
+ qemu_opt_set(opts, "ipv6", "yes");
+ return 0;
+}
+
+int inet_connect(const char *str, int socktype)
+{
+ QemuOpts *opts;
+ int sock = -1;
+
+ opts = qemu_opts_create(&dummy_opts, NULL, 0);
+ if (inet_parse(opts, str) == 0)
+ sock = inet_connect_opts(opts);
+ qemu_opts_del(opts);
+ return sock;
+}
+
#ifndef _WIN32
int unix_listen_opts(QemuOpts *opts)
diff --git a/qemu_socket.h b/qemu_socket.h
index 354c11459f..662f427279 100644
--- a/qemu_socket.h
+++ b/qemu_socket.h
@@ -38,6 +38,7 @@ int send_all(int fd, const void *buf, int len1);
/* New, ipv6-ready socket helper functions, see qemu-sockets.c */
int inet_listen(const char *str, char *ostr, int olen,
int socktype, int port_offset);
+int inet_connect_opts(QemuOpts *opts);
int inet_connect(const char *str, int socktype);
int unix_listen_opts(QemuOpts *opts);