]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cwfs/net.c
grep: error if sbrk fails
[plan9front.git] / sys / src / cmd / cwfs / net.c
1 /* network i/o */
2
3 #include "all.h"
4 #include "io.h"
5
6 /*
7  * the kernel file server read packets directly from
8  * its ethernet(s) and did all the protocol processing.
9  * if the incoming packets were 9p (over il/ip), they
10  * were queued for the server processes to operate upon.
11  *
12  * in user mode, we have one process per incoming connection
13  * instead, and those processes get just the data, minus
14  * tcp and ip headers, so they just see a stream of 9p messages,
15  * which they then queue for the server processes.
16  *
17  * there used to be more queueing (in the kernel), with separate
18  * processes for ethernet input, il input, 9p processing, il output
19  * and ethernet output, and queues connecting them.  we now let
20  * the kernel's network queues, protocol stacks and processes do
21  * much of this work.
22  *
23  * partly as a result of this, we can now process 9p messages
24  * transported via tcp, exploit multiple x86 processors, and
25  * were able to shed 70% of the file server's source, by line count.
26  *
27  * the upshot is that Ether (now Network) is no longer a perfect fit for
28  * the way network i/o is done now.  the notion of `connection'
29  * is being introduced to complement it.
30  */
31
32 typedef struct Network Network;
33
34 /* a network, not necessarily an ethernet */
35 struct Network {
36         int     ctlrno;
37         char    name[NAMELEN];
38
39         char    *dialstr;
40         char    anndir[40];
41         char    lisdir[40];
42         int     annfd;                  /* fd from announce */
43 };
44
45 static Network netif[Maxnets];
46
47 char *annstrs[Maxnets];
48
49 static void
50 neti(void *v)
51 {
52         NetConnInfo *nci;
53         Network *net;
54         char *addr;
55         int nctl, data;
56
57         net = v;
58         for(;;) {
59                 if((nctl = listen(net->anndir, net->lisdir)) < 0){
60                         fprint(2, "%s: listen %s failed: %r\n", argv0, net->anndir);
61                         break;
62                 }
63                 if((data = accept(nctl, net->lisdir)) < 0){
64                         fprint(2, "%s: accept %s failed: %r\n", argv0, net->lisdir);
65                         close(nctl);
66                         continue;
67                 }
68                 close(nctl);
69                 nci = getnetconninfo(net->lisdir, data);
70                 addr = nci == nil ? "unknown" : nci->raddr;
71                 if(srvchan(data, addr) == nil){
72                         fprint(2, "%s: srvchan failed for: %s\n", argv0, addr);
73                         close(data);
74                 }
75                 freenetconninfo(nci);
76         }
77 }
78
79 void
80 netstart(void)
81 {
82         Network *net;
83
84         for(net = &netif[0]; net < &netif[Maxnets]; net++){
85                 if(net->dialstr == nil || *net->anndir == 0)
86                         continue;
87                 sprint(net->name, "net%di", net->ctlrno);
88                 newproc(neti, net, net->name);
89         }
90 }
91
92 void
93 netinit(void)
94 {
95         Network *net;
96
97         for (net = netif; net < netif + Maxnets; net++) {
98                 net->dialstr = annstrs[net - netif];
99                 if(net->dialstr == nil)
100                         continue;
101                 if((net->annfd = announce(net->dialstr, net->anndir)) < 0){
102                         fprint(2, "can't announce %s: %r", net->dialstr);
103                         net->dialstr = nil;
104                         continue;
105                 }
106                 if(chatty)
107                         print("netinit: announced on %s\n", net->dialstr);
108         }
109 }