ubus: use network order in ubus message header fields
authorEyal Birger <eyal.birger@gmail.com>
Mon, 15 Feb 2016 04:09:38 +0000 (06:09 +0200)
committerFelix Fietkau <nbd@openwrt.org>
Sun, 28 Feb 2016 08:56:48 +0000 (09:56 +0100)
Changing the ubus message header fields from 'host' order to 'network' order
allows passing ubus messages between hosts with different endianity.

Example use (creating a ubus proxy):

on host A (e.g. big endian router already running ubusd), run:
$ socat TCP-LISTEN:5699,fork UNIX:/var/run/ubus.sock &

On host B (e.g. little endian development PC) run:
$ socat UNIX-LISTEN:/var/run/ubus.sock,fork TCP:<host A IP>:5699 &

Now ubus applications can be run on host B and seamlessly interact with ubus
applications on host A.

Signed-off-by: Eyal Birger <eyal.birger@gmail.com>
libubus-io.c
ubusd.c

index b9b312807fa08182667f40b76e204ad8829007b7..9320bf34e182454271820078e9fc8a208bedae77 100644 (file)
@@ -133,8 +133,8 @@ int __hidden ubus_send_msg(struct ubus_context *ctx, uint32_t seq,
 
        hdr.version = 0;
        hdr.type = cmd;
-       hdr.seq = seq;
-       hdr.peer = peer;
+       hdr.seq = cpu_to_be16(seq);
+       hdr.peer = cpu_to_be32(peer);
 
        if (!msg) {
                blob_buf_init(&b, 0);
@@ -281,6 +281,9 @@ static bool get_next_msg(struct ubus_context *ctx, int *recv_fd)
                return false;
        }
 
+       hdrbuf.hdr.seq = be16_to_cpu(hdrbuf.hdr.seq);
+       hdrbuf.hdr.peer = be32_to_cpu(hdrbuf.hdr.peer);
+
        if (!ubus_validate_hdr(&hdrbuf.hdr))
                return false;
 
diff --git a/ubusd.c b/ubusd.c
index f1f8ac7f003024b0661d0651f7935212c32c265a..7279a706f47e44caf92d5433326b5b733bb1b440 100644 (file)
--- a/ubusd.c
+++ b/ubusd.c
@@ -110,8 +110,15 @@ static int ubus_msg_writev(int fd, struct ubus_msg_buf *ub, int offset)
        }
 
        if (offset < sizeof(ub->hdr)) {
-               iov[0].iov_base = ((char *) &ub->hdr) + offset;
-               iov[0].iov_len = sizeof(ub->hdr) - offset;
+               struct ubus_msghdr hdr;
+
+               hdr.version = ub->hdr.version;
+               hdr.type = ub->hdr.type;
+               hdr.seq = cpu_to_be16(ub->hdr.seq);
+               hdr.peer = cpu_to_be32(ub->hdr.peer);
+
+               iov[0].iov_base = ((char *) &hdr) + offset;
+               iov[0].iov_len = sizeof(hdr) - offset;
                iov[1].iov_base = (char *) ub->data;
                iov[1].iov_len = ub->len;
 
@@ -275,6 +282,9 @@ retry:
                if (!cl->pending_msg)
                        goto disconnect;
 
+               cl->hdrbuf.hdr.seq = be16_to_cpu(cl->hdrbuf.hdr.seq);
+               cl->hdrbuf.hdr.peer = be32_to_cpu(cl->hdrbuf.hdr.peer);
+
                memcpy(&cl->pending_msg->hdr, &cl->hdrbuf.hdr, sizeof(cl->hdrbuf.hdr));
                memcpy(cl->pending_msg->data, &cl->hdrbuf.data, sizeof(cl->hdrbuf.data));
        }