Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "u.h"
2
#include "../port/lib.h"
3
#include "mem.h"
4
#include "dat.h"
5
#include "fns.h"
6
#include "../port/error.h"
7
 
8
#include "ip.h"
9
 
10
enum
11
{
12
	Maxtu=	16*1024,
13
};
14
 
15
typedef struct LB LB;
16
struct LB
17
{
18
	Proc	*readp;
19
	Queue	*q;
20
	Fs	*f;
21
};
22
 
23
static void loopbackread(void *a);
24
 
25
static void
26
loopbackbind(Ipifc *ifc, int, char**)
27
{
28
	LB *lb;
29
 
30
	lb = smalloc(sizeof(*lb));
31
	lb->f = ifc->conv->p->f;
32
	lb->q = qopen(1024*1024, Qmsg, nil, nil);
33
	ifc->arg = lb;
34
	ifc->mbps = 1000;
35
 
36
	kproc("loopbackread", loopbackread, ifc);
37
 
38
}
39
 
40
static void
41
loopbackunbind(Ipifc *ifc)
42
{
43
	LB *lb = ifc->arg;
44
 
45
	if(lb->readp)
46
		postnote(lb->readp, 1, "unbind", 0);
47
 
48
	/* wait for reader to die */
49
	while(lb->readp != 0)
50
		tsleep(&up->sleep, return0, 0, 300);
51
 
52
	/* clean up */
53
	qfree(lb->q);
54
	free(lb);
55
}
56
 
57
static void
58
loopbackbwrite(Ipifc *ifc, Block *bp, int, uchar*)
59
{
60
	LB *lb;
61
 
62
	lb = ifc->arg;
63
	if(qpass(lb->q, bp) < 0)
64
		ifc->outerr++;
65
	ifc->out++;
66
}
67
 
68
static void
69
loopbackread(void *a)
70
{
71
	Ipifc *ifc;
72
	Block *bp;
73
	LB *lb;
74
 
75
	ifc = a;
76
	lb = ifc->arg;
77
	lb->readp = up;	/* hide identity under a rock for unbind */
78
	if(waserror()){
79
		lb->readp = 0;
80
		pexit("hangup", 1);
81
	}
82
	for(;;){
83
		bp = qbread(lb->q, Maxtu);
84
		if(bp == nil)
85
			continue;
86
		ifc->in++;
87
		if(!canrlock(ifc)){
88
			freeb(bp);
89
			continue;
90
		}
91
		if(waserror()){
92
			runlock(ifc);
93
			nexterror();
94
		}
95
		if(ifc->lifc == nil)
96
			freeb(bp);
97
		else
98
			ipiput4(lb->f, ifc, bp);
99
		runlock(ifc);
100
		poperror();
101
	}
102
}
103
 
104
Medium loopbackmedium =
105
{
106
.hsize=		0,
107
.mintu=		0,
108
.maxtu=		Maxtu,
109
.maclen=	0,
110
.name=		"loopback",
111
.bind=		loopbackbind,
112
.unbind=	loopbackunbind,
113
.bwrite=	loopbackbwrite,
114
};
115
 
116
void
117
loopbackmediumlink(void)
118
{
119
	addipmedium(&loopbackmedium);
120
}