All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: agl@linux.vnet.ibm.com, abeekhof@redhat.com,
	mdroth@linux.vnet.ibm.com, aliguori@linux.vnet.ibm.com,
	ryanh@us.ibm.com, amit.shah@redhat.com
Subject: [Qemu-devel] [RFC][PATCH v3 11/21] virtproxy: add handler for control packet
Date: Mon, 15 Nov 2010 19:16:05 -0600	[thread overview]
Message-ID: <1289870175-14880-12-git-send-email-mdroth@linux.vnet.ibm.com> (raw)
In-Reply-To: <1289870175-14880-1-git-send-email-mdroth@linux.vnet.ibm.com>

Process control packets coming in over the channel. This entails setting
up/tearing down connections to local services initiated from the other
end of the channel.

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 virtproxy.c |  154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 154 insertions(+), 0 deletions(-)

diff --git a/virtproxy.c b/virtproxy.c
index a0bbe7f..0cc8950 100644
--- a/virtproxy.c
+++ b/virtproxy.c
@@ -268,6 +268,160 @@ static void vp_channel_accept(void *opaque)
     vp_set_fd_handler(drv->listen_fd, NULL, NULL, NULL);
 }
 
+/* handle control packets
+ *
+ * process VPPackets containing control messages
+ */
+static int vp_handle_control_packet(VPDriver *drv, const VPPacket *pkt)
+{
+    const VPControlMsg *msg = &pkt->payload.msg;
+    int ret;
+
+    TRACE("called with drv: %p", drv);
+
+    switch (msg->type) {
+    case VP_CONTROL_CONNECT_INIT: {
+        int client_fd = msg->args.connect_init.client_fd;
+        int server_fd;
+        char service_id[VP_SERVICE_ID_LEN];
+        VPPacket resp_pkt;
+        VPConn *new_conn;
+        VPIForward *iforward;
+
+        pstrcpy(service_id, VP_SERVICE_ID_LEN,
+                 msg->args.connect_init.service_id);
+        TRACE("setting up connection for service id %s", service_id);
+
+        /* create server connection on behalf of remote end */
+        iforward = get_iforward(drv, service_id);
+        if (iforward == NULL) {
+            LOG("no forwarder configured for service id");
+            return -1;
+        }
+
+        qemu_opts_print(iforward->socket_opts, NULL);
+        if (qemu_opt_get(iforward->socket_opts, "host") != NULL) {
+            server_fd = inet_connect_opts(iforward->socket_opts);
+        } else if (qemu_opt_get(iforward->socket_opts, "path") != NULL) {
+            server_fd = unix_connect_opts(iforward->socket_opts);
+        } else {
+            LOG("unable to find listening socket host/addr info");
+            return -1;
+        }
+
+        if (server_fd == -1) {
+            LOG("failed to create connection to service with id %s",
+                service_id);
+        }
+        TRACE("server_fd: %d", server_fd);
+
+        new_conn = qemu_mallocz(sizeof(VPConn));
+        if (!new_conn) {
+            LOG("memory allocation failed");
+            return -1;
+        }
+
+        /* send a connect_ack back over the channel */
+        /* TODO: all fields should be explicitly set so we shouldn't
+         * need to memset. this might hurt if we beef up VPPacket size
+         */
+        memset(&resp_pkt, 0, sizeof(resp_pkt));
+        resp_pkt.type = VP_PKT_CONTROL;
+        resp_pkt.payload.msg.type = VP_CONTROL_CONNECT_ACK;
+        resp_pkt.payload.msg.args.connect_ack.server_fd = server_fd;
+        resp_pkt.payload.msg.args.connect_ack.client_fd = client_fd;
+        resp_pkt.magic = VP_MAGIC;
+
+        /* TODO: can this potentially block or cause a deadlock with
+         * the remote end? need to look into potentially buffering these
+         * if it looks like the remote end is waiting for us to read data
+         * off the channel.
+         */
+        if (!drv->chr && drv->channel_fd == -1) {
+            TRACE("channel no longer connected, ignoring packet");
+            return -1;
+        }
+
+        ret = vp_channel_send_all(drv, (void *)&resp_pkt, sizeof(resp_pkt));
+        if (ret == -1) {
+            LOG("error sending data over channel");
+            return -1;
+        }
+        if (ret != sizeof(resp_pkt)) {
+            TRACE("buffer full? %d bytes remaining", ret);
+            return -1;
+        }
+
+        /* add new VPConn to list and set a read handler for it */
+        new_conn->drv = drv;
+        new_conn->client_fd = client_fd;
+        new_conn->server_fd = server_fd;
+        new_conn->type = VP_CONN_SERVER;
+        new_conn->state = VP_STATE_CONNECTED;
+        QLIST_INSERT_HEAD(&drv->conns, new_conn, next);
+        vp_set_fd_handler(server_fd, vp_conn_read, NULL, new_conn);
+
+        break;
+    }
+    case VP_CONTROL_CONNECT_ACK: {
+        int client_fd = msg->args.connect_ack.client_fd;
+        int server_fd = msg->args.connect_ack.server_fd;
+        VPConn *conn;
+
+        TRACE("recieved ack from remote end for client fd %d", client_fd);
+
+        if (server_fd <= 0) {
+            LOG("remote end sent invalid server fd");
+            return -1;
+        }
+
+        conn = get_conn(drv, client_fd, true);
+
+        if (conn == NULL) {
+            LOG("failed to find connection with client_fd %d", client_fd);
+            return -1;
+        }
+
+        conn->server_fd = server_fd;
+        conn->state = VP_STATE_CONNECTED;
+        vp_set_fd_handler(client_fd, vp_conn_read, NULL, conn);
+
+        break;
+    }
+    case VP_CONTROL_CLOSE: {
+        int fd;
+        VPConn *conn;
+
+        TRACE("closing connection on behalf of remote end");
+
+        if (msg->args.close.client_fd >= 0) {
+            fd = msg->args.close.client_fd;
+            TRACE("recieved close msg from remote end for client fd %d", fd);
+            conn = get_conn(drv, fd, true);
+        } else if (msg->args.close.server_fd >= 0) {
+            fd = msg->args.close.server_fd;
+            TRACE("recieved close msg from remote end for server fd %d", fd);
+            conn = get_conn(drv, fd, false);
+        } else {
+            LOG("invalid fd");
+            return -1;
+        }
+
+        if (conn == NULL) {
+            LOG("failed to find conn with specified fd %d", fd);
+            return -1;
+        }
+
+        closesocket(fd);
+        vp_set_fd_handler(fd, NULL, NULL, conn);
+        QLIST_REMOVE(conn, next);
+        qemu_free(conn);
+        break;
+    }
+    }
+    return 0;
+}
+
 /* handle data packets
  *
  * process VPPackets containing data and send them to the corresponding
-- 
1.7.0.4

  parent reply	other threads:[~2010-11-16  1:17 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-16  1:15 [Qemu-devel] [RFC][PATCH v3 00/21] virtproxy: host/guest communication layer Michael Roth
2010-11-16  1:15 ` [Qemu-devel] [RFC][PATCH v3 01/21] virtproxy: base data structures and constants Michael Roth
2010-11-18 11:06   ` Jes Sorensen
2010-11-18 15:35     ` Michael Roth
2010-11-18 15:41       ` Anthony Liguori
2010-11-18 15:51         ` Jes Sorensen
2010-11-18 15:56           ` Anthony Liguori
2010-11-18 16:03             ` Jes Sorensen
2010-11-16  1:15 ` [Qemu-devel] [RFC][PATCH v3 02/21] virtproxy: qemu-vp, standalone daemon skeleton Michael Roth
2010-11-18 10:04   ` Stefan Hajnoczi
2010-11-18 15:46     ` Michael Roth
2010-11-18 11:04   ` Jes Sorensen
2010-11-16  1:15 ` [Qemu-devel] [RFC][PATCH v3 03/21] virtproxy: add debug functions for virtproxy core Michael Roth
2010-11-18 11:09   ` Jes Sorensen
2010-11-18 11:43     ` Stefan Hajnoczi
2010-11-18 17:17       ` Michael Roth
2010-11-19  9:21         ` Stefan Hajnoczi
2010-11-16  1:15 ` [Qemu-devel] [RFC][PATCH v3 04/21] virtproxy: list look-up functions conns/oforwards/iforwards Michael Roth
2010-11-16  1:15 ` [Qemu-devel] [RFC][PATCH v3 05/21] virtproxy, add vp_channel_send_all Michael Roth
2010-11-18 10:08   ` Stefan Hajnoczi
2010-11-16  1:16 ` [Qemu-devel] [RFC][PATCH v3 06/21] virtproxy: add accept handler for communication channel Michael Roth
2010-11-16  1:16 ` [Qemu-devel] [RFC][PATCH v3 07/21] virtproxy: add read " Michael Roth
2010-11-16 23:17   ` Anthony Liguori
2010-11-17 21:43     ` Michael Roth
2010-11-18 10:11   ` Stefan Hajnoczi
2010-11-16  1:16 ` [Qemu-devel] [RFC][PATCH v3 08/21] virtproxy: add vp_new() VPDriver constructor Michael Roth
2010-11-16  1:16 ` [Qemu-devel] [RFC][PATCH v3 09/21] virtproxy: interfaces to set/remove/handle VPOForwards Michael Roth
2010-11-16  1:16 ` [Qemu-devel] [RFC][PATCH v3 10/21] virtproxy: add handler for data packets Michael Roth
2010-11-18 11:25   ` Jes Sorensen
2010-11-16  1:16 ` Michael Roth [this message]
2010-11-18 11:35   ` [Qemu-devel] [RFC][PATCH v3 11/21] virtproxy: add handler for control packet Jes Sorensen
2010-11-18 16:18     ` Michael Roth
2010-11-18 16:22       ` Jes Sorensen
2010-11-18 16:50         ` Michael Roth
2010-11-16  1:16 ` [Qemu-devel] [RFC][PATCH v3 12/21] virtproxy: add vp_handle_packet() Michael Roth
2010-11-16  1:16 ` [Qemu-devel] [RFC][PATCH v3 13/21] virtproxy: interfaces to set/remove VPIForwards Michael Roth
2010-11-16  1:16 ` [Qemu-devel] [RFC][PATCH v3 14/21] virtproxy: use new option list in virtproxy.c Michael Roth
2010-11-16  1:16 ` [Qemu-devel] [RFC][PATCH v3 15/21] virtproxy: add read handler for proxied connections Michael Roth
2010-11-18 11:41   ` Jes Sorensen
2010-11-16  1:16 ` [Qemu-devel] [RFC][PATCH v3 16/21] virtproxy: add option parser helper vp_parse() Michael Roth
2010-11-18 11:43   ` Jes Sorensen
2010-11-16  1:16 ` [Qemu-devel] [RFC][PATCH v3 17/21] virtproxy: add virtproxy-builtin.c for compat defs Michael Roth
2010-11-18 11:45   ` Jes Sorensen
2010-11-16  1:16 ` [Qemu-devel] [RFC][PATCH v3 18/21] virtproxy: qemu integration, add virtproxy chardev Michael Roth
2010-11-18 11:47   ` Jes Sorensen
2010-11-16  1:16 ` [Qemu-devel] [RFC][PATCH v3 19/21] virtproxy: qemu integration, add virtproxy to Makefile.targets Michael Roth
2010-11-16  1:16 ` [Qemu-devel] [RFC][PATCH v3 20/21] virtproxy: qemu-vp, main logic Michael Roth
2010-11-16  1:16 ` [Qemu-devel] [RFC][PATCH v3 21/21] virtproxy: Makefile/configure changes to build qemu-vp Michael Roth
2010-11-16 21:57 ` [Qemu-devel] [RFC][PATCH v3 00/21] virtproxy: host/guest communication layer Stefan Hajnoczi
2010-11-16 22:28   ` Michael Roth
2010-11-16 22:41     ` Michael Roth

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=1289870175-14880-12-git-send-email-mdroth@linux.vnet.ibm.com \
    --to=mdroth@linux.vnet.ibm.com \
    --cc=abeekhof@redhat.com \
    --cc=agl@linux.vnet.ibm.com \
    --cc=aliguori@linux.vnet.ibm.com \
    --cc=amit.shah@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=ryanh@us.ibm.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.