134e04225SDavid du Colombier #include <u.h>
234e04225SDavid du Colombier #include <libc.h>
334e04225SDavid du Colombier #include <ip.h>
434e04225SDavid du Colombier #include <thread.h>
534e04225SDavid du Colombier #include <sunrpc.h>
634e04225SDavid du Colombier
734e04225SDavid du Colombier typedef struct SunMsgUdp SunMsgUdp;
834e04225SDavid du Colombier struct SunMsgUdp
934e04225SDavid du Colombier {
1034e04225SDavid du Colombier SunMsg msg;
1134e04225SDavid du Colombier Udphdr udp;
1234e04225SDavid du Colombier };
1334e04225SDavid du Colombier
1434e04225SDavid du Colombier typedef struct Arg Arg;
1534e04225SDavid du Colombier struct Arg
1634e04225SDavid du Colombier {
1734e04225SDavid du Colombier SunSrv *srv;
1834e04225SDavid du Colombier Channel *creply;
1934e04225SDavid du Colombier Channel *csync;
2034e04225SDavid du Colombier int fd;
2134e04225SDavid du Colombier };
2234e04225SDavid du Colombier
2334e04225SDavid du Colombier enum
2434e04225SDavid du Colombier {
2534e04225SDavid du Colombier UdpMaxRead = 65536+Udphdrsize
2634e04225SDavid du Colombier };
27*f27a9a5aSDavid du Colombier
2834e04225SDavid du Colombier static void
sunUdpRead(void * v)2934e04225SDavid du Colombier sunUdpRead(void *v)
3034e04225SDavid du Colombier {
3134e04225SDavid du Colombier int n;
3234e04225SDavid du Colombier uchar *buf;
3334e04225SDavid du Colombier Arg arg = *(Arg*)v;
3434e04225SDavid du Colombier SunMsgUdp *msg;
3534e04225SDavid du Colombier
3634e04225SDavid du Colombier sendp(arg.csync, 0);
3734e04225SDavid du Colombier
3834e04225SDavid du Colombier buf = emalloc(UdpMaxRead);
3934e04225SDavid du Colombier while((n = read(arg.fd, buf, UdpMaxRead)) > 0){
4034e04225SDavid du Colombier if(arg.srv->chatty)
4134e04225SDavid du Colombier fprint(2, "udp got %d (%d)\n", n, Udphdrsize);
4234e04225SDavid du Colombier msg = emalloc(sizeof(SunMsgUdp));
4334e04225SDavid du Colombier memmove(&msg->udp, buf, Udphdrsize);
4434e04225SDavid du Colombier msg->msg.data = emalloc(n);
4534e04225SDavid du Colombier msg->msg.count = n-Udphdrsize;
4634e04225SDavid du Colombier memmove(msg->msg.data, buf+Udphdrsize, n-Udphdrsize);
4734e04225SDavid du Colombier memmove(&msg->udp, buf, Udphdrsize);
4834e04225SDavid du Colombier msg->msg.creply = arg.creply;
4934e04225SDavid du Colombier if(arg.srv->chatty)
5034e04225SDavid du Colombier fprint(2, "message %p count %d\n", msg, msg->msg.count);
5134e04225SDavid du Colombier sendp(arg.srv->crequest, msg);
5234e04225SDavid du Colombier }
5334e04225SDavid du Colombier }
5434e04225SDavid du Colombier
5534e04225SDavid du Colombier static void
sunUdpWrite(void * v)5634e04225SDavid du Colombier sunUdpWrite(void *v)
5734e04225SDavid du Colombier {
5834e04225SDavid du Colombier uchar *buf;
5934e04225SDavid du Colombier Arg arg = *(Arg*)v;
6034e04225SDavid du Colombier SunMsgUdp *msg;
6134e04225SDavid du Colombier
6234e04225SDavid du Colombier sendp(arg.csync, 0);
6334e04225SDavid du Colombier
6434e04225SDavid du Colombier buf = emalloc(UdpMaxRead);
6534e04225SDavid du Colombier while((msg = recvp(arg.creply)) != nil){
6634e04225SDavid du Colombier memmove(buf+Udphdrsize, msg->msg.data, msg->msg.count);
6734e04225SDavid du Colombier memmove(buf, &msg->udp, Udphdrsize);
6834e04225SDavid du Colombier msg->msg.count += Udphdrsize;
6934e04225SDavid du Colombier if(write(arg.fd, buf, msg->msg.count) != msg->msg.count)
7034e04225SDavid du Colombier fprint(2, "udpWrite: %r\n");
7134e04225SDavid du Colombier free(msg->msg.data);
7234e04225SDavid du Colombier free(msg);
7334e04225SDavid du Colombier }
7434e04225SDavid du Colombier }
7534e04225SDavid du Colombier
7634e04225SDavid du Colombier int
sunSrvUdp(SunSrv * srv,char * address)7734e04225SDavid du Colombier sunSrvUdp(SunSrv *srv, char *address)
7834e04225SDavid du Colombier {
7934e04225SDavid du Colombier int acfd, fd;
8034e04225SDavid du Colombier char adir[40], data[60];
8134e04225SDavid du Colombier Arg *arg;
8234e04225SDavid du Colombier
8334e04225SDavid du Colombier acfd = announce(address, adir);
8434e04225SDavid du Colombier if(acfd < 0)
85fb7f0c93SDavid du Colombier return -1;
8634e04225SDavid du Colombier if(write(acfd, "headers", 7) < 0){
8734e04225SDavid du Colombier werrstr("setting headers: %r");
8834e04225SDavid du Colombier close(acfd);
89fb7f0c93SDavid du Colombier return -1;
9034e04225SDavid du Colombier }
9134e04225SDavid du Colombier snprint(data, sizeof data, "%s/data", adir);
9234e04225SDavid du Colombier if((fd = open(data, ORDWR)) < 0){
9334e04225SDavid du Colombier werrstr("open %s: %r", data);
9434e04225SDavid du Colombier close(acfd);
95fb7f0c93SDavid du Colombier return -1;
9634e04225SDavid du Colombier }
9734e04225SDavid du Colombier close(acfd);
9834e04225SDavid du Colombier
9934e04225SDavid du Colombier arg = emalloc(sizeof(Arg));
10034e04225SDavid du Colombier arg->fd = fd;
10134e04225SDavid du Colombier arg->srv = srv;
10234e04225SDavid du Colombier arg->creply = chancreate(sizeof(SunMsg*), 10);
10334e04225SDavid du Colombier arg->csync = chancreate(sizeof(void*), 10);
10434e04225SDavid du Colombier
10534e04225SDavid du Colombier proccreate(sunUdpRead, arg, SunStackSize);
10634e04225SDavid du Colombier proccreate(sunUdpWrite, arg, SunStackSize);
10734e04225SDavid du Colombier recvp(arg->csync);
10834e04225SDavid du Colombier recvp(arg->csync);
10934e04225SDavid du Colombier chanfree(arg->csync);
11034e04225SDavid du Colombier free(arg);
11134e04225SDavid du Colombier
112fb7f0c93SDavid du Colombier return 0;
11334e04225SDavid du Colombier }
114