Implement receiving from multiple sources. Also modify the tests for this.
authorAdrian Bondrescu <adi.bondrescu@gmail.com>
Sun, 27 May 2012 11:03:20 +0000 (14:03 +0300)
committerAdrian Bondrescu <adi.bondrescu@gmail.com>
Sun, 27 May 2012 11:03:20 +0000 (14:03 +0300)
src/kernel/swift.c
test/client.c
test/server.c

index 9e79e02..63004b1 100644 (file)
@@ -356,6 +356,8 @@ static int swift_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
        struct sockaddr_swift *swift_addr;
        struct sock * sk = sock->sk;
        int err, copied;
+       int i;
+       struct sockaddr_swift *ret_addr = (struct sockaddr_swift *) msg->msg_name;
 
     log_debug("Trying to receive sock=%p sk=%p flags=%d\n", sock, sk, flags);
 
@@ -365,32 +367,43 @@ static int swift_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
                goto out;
        }
 
-       log_debug("Received skb %p\n", skb);
+       for (i = 0; i < msg->msg_iovlen; i++) {
+               log_debug("Received skb %p\n", skb);
 
-       swift_addr = (struct sockaddr_swift *) skb->cb;
-       msg->msg_namelen = sizeof(struct sockaddr_swift);
+               swift_addr = (struct sockaddr_swift *) skb->cb;
 
-       copied = skb->len;
-       if (copied > len) {
-               copied = len;
-               msg->msg_flags |= MSG_TRUNC;
-       }
+               copied = skb->len;
+               if (copied > msg->msg_iov[i].iov_len) {
+                       copied = msg->msg_iov[i].iov_len;
+                       msg->msg_flags |= MSG_TRUNC;
+               }
 
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
-       if (unlikely(err)) {
-               log_error("skb_copy_datagram_iovec\n");
-               goto out_free;
-       }
+               err = skb_copy_datagram_iovec(skb, 0, &msg->msg_iov[i], copied);
+               if (unlikely(err)) {
+                       log_error("skb_copy_datagram_iovec\n");
+                       goto out_free;
+               }
 
-       sock_recv_ts_and_drops(msg, sk, skb);
+               sock_recv_ts_and_drops(msg, sk, skb);
 
-       if (msg->msg_name)
-               memcpy(msg->msg_name, swift_addr, msg->msg_namelen);
-       
-       err = copied;
+               if (ret_addr)
+                       memcpy(&ret_addr->dests[i], &swift_addr->dests[0], sizeof(ret_addr->dests[i]));
+
+               err = copied;
 
 out_free:
-       skb_free_datagram(sk, skb);
+           skb_free_datagram(sk, skb);
+
+               skb = skb_recv_datagram(sk, flags, 1, &err);
+               if (likely(err == -EAGAIN)) {
+                       log_debug("No more skbs in the queue, returning...\n");
+                       err = copied;
+                       break;
+               }
+       }
+
+       ret_addr->count = i + 1;
+       msg->msg_namelen = sizeof(struct sockaddr_swift) + (i + 1) * sizeof(struct swift_dest);
 
 out:
        return err;
@@ -404,6 +417,7 @@ static int swift_rcv(struct sk_buff *skb)
        uint8_t src, dst;
        struct sockaddr_swift * swift_addr;
        int err;
+       int addr_size = sizeof(struct sockaddr_swift) + sizeof(struct swift_dest);
 
        if (unlikely(!pskb_may_pull(skb, sizeof(struct swifthdr)))) {
                log_error("Insufficient space for header\n");
@@ -443,7 +457,7 @@ static int swift_rcv(struct sk_buff *skb)
                goto drop;
        }
 
-       BUILD_BUG_ON(sizeof(struct sockaddr_swift) > sizeof(skb->cb));
+       BUG_ON(addr_size > sizeof(skb->cb));
        
        swift_addr = (struct sockaddr_swift *) skb->cb;
        swift_addr->dests[0].port = shdr->src;
index b2e58d6..2f8e87a 100644 (file)
@@ -6,9 +6,21 @@
 #include <string.h>
 #include <netinet/in.h>
 #include <stdlib.h>
+#include <time.h>
 
-#define ADDR 0x80BEA8C0
-#define DADDR 0x81BEA8C0
+#define ADDR 0x8082A8C0
+#define DADDR 0x8082A8C0
+
+int gen_port()
+{
+       int ret;
+       srand(time(NULL));
+       ret = (rand() % 255) + 1;
+       if (ret == 100 || ret == 101)
+               ret *= 2;
+       printf("Generated source port %d\n", ret);
+       return ret;
+}
 
 int main(int argc, const char *argv[])
 {
@@ -26,7 +38,7 @@ int main(int argc, const char *argv[])
 
     saddr->count = 1;
     saddr->dests[0].addr = ADDR;
-    saddr->dests[0].port = 50;
+    saddr->dests[0].port = gen_port();
 
     if (bind(sock, (struct sockaddr *) saddr, size) < 0) {
         perror("Failed to bind socket");
@@ -34,7 +46,7 @@ int main(int argc, const char *argv[])
         return -1;
     }
 
-    char buf[] = "Buffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de testBuffer de test";
+    char buf[] = "Buffer1";
     char buf2[] = "Buffer2";
     struct iovec iov[2];
     struct msghdr msg;
index c25384a..139e89b 100644 (file)
@@ -7,11 +7,13 @@
 #include <netinet/in.h>
 #include <stdlib.h>
 
-#define ADDR 0x81BEA8C0
+#define ADDR 0x8182A8C0
+#define NUM_BUF 10
 
 int main(int argc, const char *argv[])
 {
     int sock;
+       int i;
 
     if (argc != 2) {
         fprintf(stderr, "USAGE: %s listening_port\n", argv[0]);
@@ -38,25 +40,30 @@ int main(int argc, const char *argv[])
         return -1;
     }
 
-    char buf[10240];
-    struct iovec iov[1];
+    char buf[NUM_BUF][10240];
+    struct iovec iov[NUM_BUF];
     struct msghdr msg;
+       size += (NUM_BUF - 1) * sizeof(struct swift_dest);
     struct sockaddr_swift *from = malloc(size);
 
     memset(&msg, 0, sizeof(msg));
     memset(&iov, 0, sizeof(iov));
     memset(from, 0, size);
 
-    iov[0].iov_base = buf;
-    iov[0].iov_len = sizeof(buf);
+       for (i = 0; i < NUM_BUF; i++) {
+               iov[i].iov_base = buf[i];
+               iov[i].iov_len = sizeof(buf[i]);
+       }
 
     msg.msg_iov = iov;
-    msg.msg_iovlen = 1;
+    msg.msg_iovlen = 10;
     msg.msg_name = from;
     msg.msg_namelen = size;
 
     int ret, fromlen;
 
+       sleep(20);
+
     ret = recvmsg(sock, &msg, 0);
     if (ret < 0) {
         perror("Failed to recv on socket");
@@ -64,7 +71,9 @@ int main(int argc, const char *argv[])
     }
 
     printf("Received %d bytes on socket\n", ret);
-    printf("buf=%s\n", buf);
+       for (i = 0; i < from->count; i++) {
+               printf("buf=%s from %s:%d\n", buf[i], inet_ntoa(from->dests[i].addr), from->dests[i].port);
+       }
 
     if (close(sock) < 0) {
         perror("Failed to close socket");