URI:
       tudp.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tudp.c (2544B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <ip.h>
            4 #include <thread.h>
            5 #include <sunrpc.h>
            6 
            7 typedef struct SunMsgUdp SunMsgUdp;
            8 struct SunMsgUdp
            9 {
           10         SunMsg msg;
           11         Udphdr udp;
           12 };
           13 
           14 typedef struct Arg Arg;
           15 struct Arg
           16 {
           17         SunSrv *srv;
           18         Channel *creply;
           19         Channel *csync;
           20         int fd;
           21 };
           22 
           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];
           37 
           38         sendp(arg.csync, 0);
           39         srv = arg.srv;
           40         paraport = -1;
           41 
           42         /* 127.1 */
           43         memmove(localip, v4prefix, IPaddrlen);
           44         localip[12] = 127;
           45         localip[15] = 1;
           46 
           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 }
           81 
           82 static void
           83 sunudpwrite(void *v)
           84 {
           85         Arg arg = *(Arg*)v;
           86         SunMsgUdp *msg;
           87 
           88         sendp(arg.csync, 0);
           89 
           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 }
           96 
           97 int
           98 sunsrvudp(SunSrv *srv, char *address)
           99 {
          100         int fd;
          101         char adir[40];
          102         Arg *arg;
          103 
          104         fd = announce(address, adir);
          105         if(fd < 0)
          106                 return -1;
          107 
          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);
          113 
          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);
          120 
          121         return 0;
          122 }