qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: anthony@codemonkey.ws
Cc: kwolf@redhat.com, qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 11/15] NBD: Use qemu_socket functions to open TCP and UNIX sockets
Date: Thu,  7 Apr 2011 16:49:20 +0200	[thread overview]
Message-ID: <1302187764-16421-12-git-send-email-kwolf@redhat.com> (raw)
In-Reply-To: <1302187764-16421-1-git-send-email-kwolf@redhat.com>

From: Nick Thomas <nick@bytemark.co.uk>

This commit has the side-effect of making the qemu-nbd binary
capable of binding to IPv6 addresses. ("-b ::1", for instance).
block/nbd.c fails to parse IPv6 IP addresses correctly at this
point, but will work over IPv6 when given a hostname. It still
works over IPv4 as before.

We move the qemu-sockets object from the 'common' to the 'block'
list in the Makefile. The common list includes the block list,
so this is effectively a no-op for the rest of the code.

We also add 32-bit 'magic' attributes to nbd_(request|reply) to
facilitate calculating maximum request/response sizes later.

Signed-off-by: Nick Thomas <nick@bytemark.co.uk>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 Makefile.objs |    4 +-
 nbd.c         |  158 ++++++++++----------------------------------------------
 nbd.h         |    9 +++-
 3 files changed, 38 insertions(+), 133 deletions(-)

diff --git a/Makefile.objs b/Makefile.objs
index 94587e1..44ce368 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -14,7 +14,7 @@ oslib-obj-$(CONFIG_POSIX) += oslib-posix.o
 # block-obj-y is code used by both qemu system emulation and qemu-img
 
 block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o async.o
-block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o qemu-progress.o
+block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o qemu-progress.o qemu-sockets.o
 block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
 block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
 
@@ -94,7 +94,7 @@ common-obj-$(CONFIG_SSI_SD) += ssi-sd.o
 common-obj-$(CONFIG_SD) += sd.o
 common-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o
 common-obj-y += bt-hci-csr.o
-common-obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o
+common-obj-y += buffered_file.o migration.o migration-tcp.o
 common-obj-y += qemu-char.o savevm.o #aio.o
 common-obj-y += msmouse.o ps2.o
 common-obj-y += qdev.o qdev-properties.o
diff --git a/nbd.c b/nbd.c
index abe0ecb..0dcd86b 100644
--- a/nbd.c
+++ b/nbd.c
@@ -107,155 +107,55 @@ size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read)
     return offset;
 }
 
-int tcp_socket_outgoing(const char *address, uint16_t port)
+static void combine_addr(char *buf, size_t len, const char* address,
+                         uint16_t port)
 {
-    int s;
-    struct in_addr in;
-    struct sockaddr_in addr;
-
-    s = socket(PF_INET, SOCK_STREAM, 0);
-    if (s == -1) {
-        return -1;
-    }
-
-    if (inet_aton(address, &in) == 0) {
-        struct hostent *ent;
-
-        ent = gethostbyname(address);
-        if (ent == NULL) {
-            goto error;
-        }
-
-        memcpy(&in, ent->h_addr, sizeof(in));
-    }
-
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(port);
-    memcpy(&addr.sin_addr.s_addr, &in, sizeof(in));
-
-    if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
-        goto error;
+    /* If the address-part contains a colon, it's an IPv6 IP so needs [] */
+    if (strstr(address, ":")) {
+        snprintf(buf, len, "[%s]:%u", address, port);
+    } else {
+        snprintf(buf, len, "%s:%u", address, port);
     }
-
-    return s;
-error:
-    closesocket(s);
-    return -1;
 }
 
-int tcp_socket_incoming(const char *address, uint16_t port)
+int tcp_socket_outgoing(const char *address, uint16_t port)
 {
-    int s;
-    struct in_addr in;
-    struct sockaddr_in addr;
-    int opt;
-
-    s = socket(PF_INET, SOCK_STREAM, 0);
-    if (s == -1) {
-        return -1;
-    }
-
-    if (inet_aton(address, &in) == 0) {
-        struct hostent *ent;
-
-        ent = gethostbyname(address);
-        if (ent == NULL) {
-            goto error;
-        }
-
-        memcpy(&in, ent->h_addr, sizeof(in));
-    }
-
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(port);
-    memcpy(&addr.sin_addr.s_addr, &in, sizeof(in));
-
-    opt = 1;
-    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
-                   (const void *) &opt, sizeof(opt)) == -1) {
-        goto error;
-    }
-
-    if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
-        goto error;
-    }
-
-    if (listen(s, 128) == -1) {
-        goto error;
-    }
-
-    return s;
-error:
-    closesocket(s);
-    return -1;
+    char address_and_port[128];
+    combine_addr(address_and_port, 128, address, port);
+    return tcp_socket_outgoing_spec(address_and_port);
 }
 
-#ifndef _WIN32
-int unix_socket_incoming(const char *path)
+int tcp_socket_outgoing_spec(const char *address_and_port)
 {
-    int s;
-    struct sockaddr_un addr;
-
-    s = socket(PF_UNIX, SOCK_STREAM, 0);
-    if (s == -1) {
-        return -1;
-    }
-
-    memset(&addr, 0, sizeof(addr));
-    addr.sun_family = AF_UNIX;
-    pstrcpy(addr.sun_path, sizeof(addr.sun_path), path);
-
-    if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
-        goto error;
-    }
-
-    if (listen(s, 128) == -1) {
-        goto error;
-    }
-
-    return s;
-error:
-    closesocket(s);
-    return -1;
+    return inet_connect(address_and_port, SOCK_STREAM);
 }
 
-int unix_socket_outgoing(const char *path)
+int tcp_socket_incoming(const char *address, uint16_t port)
 {
-    int s;
-    struct sockaddr_un addr;
-
-    s = socket(PF_UNIX, SOCK_STREAM, 0);
-    if (s == -1) {
-        return -1;
-    }
-
-    memset(&addr, 0, sizeof(addr));
-    addr.sun_family = AF_UNIX;
-    pstrcpy(addr.sun_path, sizeof(addr.sun_path), path);
-
-    if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
-        goto error;
-    }
+    char address_and_port[128];
+    combine_addr(address_and_port, 128, address, port);
+    return tcp_socket_incoming_spec(address_and_port);
+}
 
-    return s;
-error:
-    closesocket(s);
-    return -1;
+int tcp_socket_incoming_spec(const char *address_and_port)
+{
+    char *ostr  = NULL;
+    int olen = 0;
+    return inet_listen(address_and_port, ostr, olen, SOCK_STREAM, 0);
 }
-#else
+
 int unix_socket_incoming(const char *path)
 {
-    errno = ENOTSUP;
-    return -1;
+    char *ostr = NULL;
+    int olen = 0;
+
+    return unix_listen(path, ostr, olen);
 }
 
 int unix_socket_outgoing(const char *path)
 {
-    errno = ENOTSUP;
-    return -1;
+    return unix_connect(path);
 }
-#endif
-
 
 /* Basic flow
 
diff --git a/nbd.h b/nbd.h
index fc3a594..b38d0d0 100644
--- a/nbd.h
+++ b/nbd.h
@@ -22,19 +22,22 @@
 #include <sys/types.h>
 
 #include <qemu-common.h>
+
 #include "block_int.h"
 
 struct nbd_request {
+    uint32_t magic;
     uint32_t type;
     uint64_t handle;
     uint64_t from;
     uint32_t len;
-};
+} __attribute__ ((__packed__));
 
 struct nbd_reply {
+    uint32_t magic;
     uint32_t error;
     uint64_t handle;
-};
+} __attribute__ ((__packed__));
 
 enum {
     NBD_CMD_READ = 0,
@@ -47,6 +50,8 @@ enum {
 size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read);
 int tcp_socket_outgoing(const char *address, uint16_t port);
 int tcp_socket_incoming(const char *address, uint16_t port);
+int tcp_socket_outgoing_spec(const char *address_and_port);
+int tcp_socket_incoming_spec(const char *address_and_port);
 int unix_socket_outgoing(const char *path);
 int unix_socket_incoming(const char *path);
 
-- 
1.7.2.3

  parent reply	other threads:[~2011-04-07 14:47 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-07 14:49 [Qemu-devel] [PULL 00/15] Block patches Kevin Wolf
2011-04-07 14:49 ` [Qemu-devel] [PATCH 01/15] hw/xen_disk: ioreq not finished on error Kevin Wolf
2011-04-07 14:49 ` [Qemu-devel] [PATCH 02/15] Do not delete BlockDriverState when deleting the drive Kevin Wolf
2011-04-07 14:49 ` [Qemu-devel] [PATCH 03/15] trace: Trace bdrv_set_locked() Kevin Wolf
2011-04-07 14:49 ` [Qemu-devel] [PATCH 04/15] block: Do not cache device size for removable media Kevin Wolf
2011-04-07 14:49 ` [Qemu-devel] [PATCH 05/15] qemu-img: Initial progress printing support Kevin Wolf
2011-04-07 14:49 ` [Qemu-devel] [PATCH 06/15] qemu-img rebase: Fix segfault if backing file can't be opened Kevin Wolf
2011-04-07 14:49 ` [Qemu-devel] [PATCH 07/15] exit if -drive specified is invalid instead of ignoring the "wrong" -drive Kevin Wolf
2011-04-07 14:49 ` [Qemu-devel] [PATCH 08/15] ide: consolidate drive_get(IF_IDE) Kevin Wolf
2011-04-07 14:49 ` [Qemu-devel] [PATCH 09/15] NBD library: whitespace changes Kevin Wolf
2011-04-07 14:49 ` [Qemu-devel] [PATCH 10/15] Set errno=ENOTSUP for attempts to use UNIX sockets on Windows platforms Kevin Wolf
2011-04-07 14:49 ` Kevin Wolf [this message]
2011-04-07 14:49 ` [Qemu-devel] [PATCH 12/15] NBD device: Separate out parsing configuration and opening sockets Kevin Wolf
2011-04-07 14:49 ` [Qemu-devel] [PATCH 13/15] floppy: save and restore DIR register Kevin Wolf
2011-04-07 14:49 ` [Qemu-devel] [PATCH 14/15] Fix integer overflow in block migration bandwidth calculation Kevin Wolf
2011-04-07 14:49 ` [Qemu-devel] [PATCH 15/15] virtio-blk: fail unaligned requests Kevin Wolf
2011-04-07 15:44 ` [Qemu-devel] [PULL 00/15] Block patches Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1302187764-16421-12-git-send-email-kwolf@redhat.com \
    --to=kwolf@redhat.com \
    --cc=anthony@codemonkey.ws \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).