Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <ip.h>
4 #include <thread.h>
5 #include <sunrpc.h>
7 typedef struct SunMsgUdp SunMsgUdp;
8 struct SunMsgUdp
9 {
10 SunMsg msg;
11 Udphdr udp;
12 };
14 typedef struct Arg Arg;
15 struct Arg
16 {
17 SunSrv *srv;
18 Channel *creply;
19 Channel *csync;
20 int fd;
21 };
23 enum
24 {
25 UdpMaxRead = 65536+Udphdrsize
26 };
27 static void
28 sunudpread(void *v)
29 {
30 int n, paraport, port;
31 uchar *buf;
32 Arg arg = *(Arg*)v;
33 SunMsgUdp *msg;
34 SunSrv *srv;
35 Udphdr udp;
36 uchar localip[IPaddrlen];
38 sendp(arg.csync, 0);
39 srv = arg.srv;
40 paraport = -1;
42 /* 127.1 */
43 memmove(localip, v4prefix, IPaddrlen);
44 localip[12] = 127;
45 localip[15] = 1;
47 buf = emalloc(UdpMaxRead);
48 while((n = udpread(arg.fd, &udp, buf, UdpMaxRead)) > 0){
49 if(arg.srv->chatty)
50 fprint(2, "udpread got %d (%d) from %I\n", n, Udphdrsize, udp.raddr);
51 msg = emalloc(sizeof(SunMsgUdp));
52 msg->udp = udp;
53 msg->msg.data = emalloc(n);
54 msg->msg.count = n;
55 memmove(msg->msg.data, buf, n);
56 msg->msg.creply = arg.creply;
57 msg->msg.srv = arg.srv;
58 if(arg.srv->chatty)
59 fprint(2, "message %p count %d\n", msg, msg->msg.count);
60 if((srv->localonly || srv->localparanoia) && ipcmp(udp.raddr, localip) != 0){
61 fprint(2, "dropping message from %I: not local\n", udp.raddr);
62 sunmsgreplyerror(&msg->msg, SunAuthTooWeak);
63 continue;
64 }
65 if(srv->localparanoia){
66 port = nhgets(udp.rport);
67 if(paraport == -1){
68 fprint(2, "paranoid mode: only %I/%d allowed\n", localip, port);
69 paraport = port;
70 }else if(paraport != port){
71 fprint(2, "dropping message from %I: not port %d\n", udp.raddr, port);
72 sunmsgreplyerror(&msg->msg, SunAuthTooWeak);
73 continue;
74 }
75 }
76 if(srv->ipokay && !srv->ipokay(udp.raddr, nhgets(udp.rport)))
77 msg->msg.rpc.status = SunProgUnavail;
78 sendp(arg.srv->crequest, msg);
79 }
80 }
82 static void
83 sunudpwrite(void *v)
84 {
85 Arg arg = *(Arg*)v;
86 SunMsgUdp *msg;
88 sendp(arg.csync, 0);
90 while((msg = recvp(arg.creply)) != nil){
91 if(udpwrite(arg.fd, &msg->udp, msg->msg.data, msg->msg.count) != msg->msg.count)
92 fprint(2, "udpwrite: %r\n");
93 sunmsgdrop(&msg->msg);
94 }
95 }
97 int
98 sunsrvudp(SunSrv *srv, char *address)
99 {
100 int fd;
101 char adir[40];
102 Arg *arg;
104 fd = announce(address, adir);
105 if(fd < 0)
106 return -1;
108 arg = emalloc(sizeof(Arg));
109 arg->fd = fd;
110 arg->srv = srv;
111 arg->creply = chancreate(sizeof(SunMsg*), 10);
112 arg->csync = chancreate(sizeof(void*), 10);
114 proccreate(sunudpread, arg, SunStackSize);
115 proccreate(sunudpwrite, arg, SunStackSize);
116 recvp(arg->csync);
117 recvp(arg->csync);
118 chanfree(arg->csync);
119 free(arg);
121 return 0;