summaryrefslogtreecommitdiff
path: root/sys/src/libsunrpc/udp.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libsunrpc/udp.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libsunrpc/udp.c')
-rwxr-xr-xsys/src/libsunrpc/udp.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/sys/src/libsunrpc/udp.c b/sys/src/libsunrpc/udp.c
new file mode 100755
index 000000000..8e0697c91
--- /dev/null
+++ b/sys/src/libsunrpc/udp.c
@@ -0,0 +1,113 @@
+#include <u.h>
+#include <libc.h>
+#include <ip.h>
+#include <thread.h>
+#include <sunrpc.h>
+
+typedef struct SunMsgUdp SunMsgUdp;
+struct SunMsgUdp
+{
+ SunMsg msg;
+ Udphdr udp;
+};
+
+typedef struct Arg Arg;
+struct Arg
+{
+ SunSrv *srv;
+ Channel *creply;
+ Channel *csync;
+ int fd;
+};
+
+enum
+{
+ UdpMaxRead = 65536+Udphdrsize
+};
+
+static void
+sunUdpRead(void *v)
+{
+ int n;
+ uchar *buf;
+ Arg arg = *(Arg*)v;
+ SunMsgUdp *msg;
+
+ sendp(arg.csync, 0);
+
+ buf = emalloc(UdpMaxRead);
+ while((n = read(arg.fd, buf, UdpMaxRead)) > 0){
+ if(arg.srv->chatty)
+ fprint(2, "udp got %d (%d)\n", n, Udphdrsize);
+ msg = emalloc(sizeof(SunMsgUdp));
+ memmove(&msg->udp, buf, Udphdrsize);
+ msg->msg.data = emalloc(n);
+ msg->msg.count = n-Udphdrsize;
+ memmove(msg->msg.data, buf+Udphdrsize, n-Udphdrsize);
+ memmove(&msg->udp, buf, Udphdrsize);
+ msg->msg.creply = arg.creply;
+ if(arg.srv->chatty)
+ fprint(2, "message %p count %d\n", msg, msg->msg.count);
+ sendp(arg.srv->crequest, msg);
+ }
+}
+
+static void
+sunUdpWrite(void *v)
+{
+ uchar *buf;
+ Arg arg = *(Arg*)v;
+ SunMsgUdp *msg;
+
+ sendp(arg.csync, 0);
+
+ buf = emalloc(UdpMaxRead);
+ while((msg = recvp(arg.creply)) != nil){
+ memmove(buf+Udphdrsize, msg->msg.data, msg->msg.count);
+ memmove(buf, &msg->udp, Udphdrsize);
+ msg->msg.count += Udphdrsize;
+ if(write(arg.fd, buf, msg->msg.count) != msg->msg.count)
+ fprint(2, "udpWrite: %r\n");
+ free(msg->msg.data);
+ free(msg);
+ }
+}
+
+int
+sunSrvUdp(SunSrv *srv, char *address)
+{
+ int acfd, fd;
+ char adir[40], data[60];
+ Arg *arg;
+
+ acfd = announce(address, adir);
+ if(acfd < 0)
+ return -1;
+ if(write(acfd, "headers", 7) < 0){
+ werrstr("setting headers: %r");
+ close(acfd);
+ return -1;
+ }
+ snprint(data, sizeof data, "%s/data", adir);
+ if((fd = open(data, ORDWR)) < 0){
+ werrstr("open %s: %r", data);
+ close(acfd);
+ return -1;
+ }
+ close(acfd);
+
+ arg = emalloc(sizeof(Arg));
+ arg->fd = fd;
+ arg->srv = srv;
+ arg->creply = chancreate(sizeof(SunMsg*), 10);
+ arg->csync = chancreate(sizeof(void*), 10);
+
+ proccreate(sunUdpRead, arg, SunStackSize);
+ proccreate(sunUdpWrite, arg, SunStackSize);
+ recvp(arg->csync);
+ recvp(arg->csync);
+ chanfree(arg->csync);
+ free(arg);
+
+ return 0;
+}