Annotation of embedaddon/mpd/src/rep.c, revision 1.1.1.1
1.1 misho 1:
2: /*
3: * rep.c
4: *
5: * Written by Alexander Motin <mav@FreeBSD.org>
6: */
7:
8: #include "ppp.h"
9: #include "rep.h"
10: #include "msg.h"
11: #include "ngfunc.h"
12: #include "log.h"
13: #include "util.h"
14:
15: #include <netgraph/ng_message.h>
16: #include <netgraph/ng_socket.h>
17: #include <netgraph/ng_tee.h>
18: #include <netgraph.h>
19:
20: /*
21: * INTERNAL FUNCTIONS
22: */
23:
24: static void RepShowLinks(Context ctx, Rep r);
25:
26: /*
27: * RepIncoming()
28: */
29:
30: void
31: RepIncoming(Link l)
32: {
33: Rep r = l->rep;
34: struct ngm_mkpeer mkp;
35: char buf[64];
36:
37: Log(LG_REP, ("[%s] Rep: INCOMING event from %s (0)",
38: r->name, l->name));
39:
40: if (r->csock <= 0) {
41: /* Create a new netgraph node to control TCP ksocket node. */
42: if (NgMkSockNode(NULL, &r->csock, NULL) < 0) {
43: Perror("[%s] Rep: can't create control socket", r->name);
44: PhysClose(l);
45: return;
46: }
47: (void)fcntl(r->csock, F_SETFD, 1);
48: }
49:
50: strcpy(mkp.type, NG_TEE_NODE_TYPE);
51: snprintf(mkp.ourhook, sizeof(mkp.ourhook), "tee");
52: snprintf(mkp.peerhook, sizeof(mkp.peerhook), NG_TEE_HOOK_LEFT2RIGHT);
53: if (NgSendMsg(r->csock, ".:", NGM_GENERIC_COOKIE,
54: NGM_MKPEER, &mkp, sizeof(mkp)) < 0) {
55: Perror("[%s] Rep: can't attach %s %s node",
56: l->name, NG_TEE_NODE_TYPE, mkp.ourhook);
57: close(r->csock);
58: PhysClose(l);
59: return;
60: }
61:
62: /* Get tee node ID */
63: if ((r->node_id = NgGetNodeID(r->csock, ".:tee")) == 0) {
64: Perror("[%s] Rep: Cannot get %s node id", l->name, NG_TEE_NODE_TYPE);
65: close(r->csock);
66: PhysClose(l);
67: return;
68: };
69:
70: PhysGetCallingNum(r->links[0], buf, sizeof(buf));
71: PhysSetCallingNum(r->links[1], buf);
72:
73: PhysGetCalledNum(r->links[0], buf, sizeof(buf));
74: PhysSetCalledNum(r->links[1], buf);
75:
76: PhysOpen(r->links[1]);
77: }
78:
79: /*
80: * RepUp()
81: */
82:
83: void
84: RepUp(Link l)
85: {
86: Rep r = l->rep;
87: int n = (r->links[0] == l)?0:1;
88:
89: Log(LG_REP, ("[%s] Rep: UP event from %s (%d)",
90: r->name, l->name, n));
91:
92: r->p_up |= (1 << n);
93:
94: if (n == 1)
95: PhysOpen(r->links[1-n]);
96:
97: if (r->p_up == 3 && r->csock > 0 && r->node_id) {
98: char path[NG_PATHSIZ];
99:
100: snprintf(path, sizeof(path), "[%x]:", r->node_id);
101: NgFuncShutdownNode(r->csock, r->name, path);
102: r->node_id = 0;
103: close(r->csock);
104: r->csock = -1;
105: }
106: }
107:
108: /*
109: * RepDown()
110: */
111:
112: void
113: RepDown(Link l)
114: {
115: Rep r = l->rep;
116: int n = (r->links[0] == l)?0:1;
117:
118: Log(LG_REP, ("[%s] Rep: DOWN event from %s (%d)",
119: r->name, l->name, n));
120:
121: r->p_up &= ~(1 << n);
122:
123: if (r->links[1-n])
124: PhysClose(r->links[1-n]);
125:
126: if (r->csock > 0 && r->node_id) {
127: char path[NG_PATHSIZ];
128:
129: snprintf(path, sizeof(path), "[%x]:", r->node_id);
130: NgFuncShutdownNode(r->csock, r->name, path);
131: r->node_id = 0;
132: close(r->csock);
133: r->csock = -1;
134: }
135:
136: l->rep->links[n] = NULL;
137: l->rep = NULL;
138: if (!l->stay) {
139: REF(l);
140: MsgSend(&l->msgs, MSG_SHUTDOWN, l);
141: }
142:
143: if (r->links[1-n] == NULL)
144: RepShutdown(r);
145: }
146:
147: /*
148: * RepIsSync()
149: */
150:
151: int
152: RepIsSync(Link l) {
153: Rep r = l->rep;
154: int n = (r->links[0] == l)?0:1;
155:
156: if (r->links[1-n])
157: return (PhysIsSync(r->links[1-n]));
158: else
159: return (0);
160: }
161:
162: /*
163: * RepSetAccm()
164: */
165:
166: void
167: RepSetAccm(Link l, u_int32_t xmit, u_int32_t recv) {
168: Rep r = l->rep;
169: int n = (r->links[0] == l)?0:1;
170:
171: Log(LG_REP, ("[%s] Rep: SetAccm(0x%08x, 0x%08x) from %s (%d)",
172: r->name, xmit, recv, l->name, n));
173:
174: if (r->links[1-n])
175: PhysSetAccm(r->links[1-n], xmit, recv);
176: }
177:
178: /*
179: * RepGetHook()
180: */
181:
182: int
183: RepGetHook(Link l, char *path, char *hook)
184: {
185: Rep r = l->rep;
186: int n = (r->links[0] == l)?0:1;
187:
188: if (r->node_id == 0)
189: return (0);
190:
191: snprintf(path, NG_PATHSIZ, "[%lx]:", (u_long)r->node_id);
192: if (n == 0)
193: snprintf(hook, NG_HOOKSIZ, NG_TEE_HOOK_LEFT);
194: else
195: snprintf(hook, NG_HOOKSIZ, NG_TEE_HOOK_RIGHT);
196: return (1);
197: }
198:
199: /*
200: * RepCommand()
201: *
202: * Show list of all bundles or set bundle
203: */
204:
205: int
206: RepCommand(Context ctx, int ac, char *av[], void *arg)
207: {
208: Rep r;
209: int k;
210:
211: if (ac > 1)
212: return (-1);
213:
214: if (ac == 0) {
215: Printf("Defined repeaters:\r\n");
216: for (k = 0; k < gNumReps; k++) {
217: if ((r = gReps[k]) != NULL) {
218: Printf("\t%-15s%s %s\n",
219: r->name, r->links[0]->name, r->links[1]->name);
220: }
221: }
222: return (0);
223: }
224:
225: if ((r = RepFind(av[0])) == NULL) {
226: RESETREF(ctx->rep, NULL);
227: RESETREF(ctx->bund, NULL);
228: RESETREF(ctx->lnk, NULL);
229: Error("Repeater \"%s\" not defined.", av[0]);
230: }
231:
232: /* Change repeater, and link also if needed */
233: RESETREF(ctx->rep, r);
234: RESETREF(ctx->bund, NULL);
235: RESETREF(ctx->lnk, r->links[0]);
236:
237: return(0);
238: }
239:
240: /*
241: * RepCreate()
242: *
243: * Create a new repeater.
244: */
245:
246: int
247: RepCreate(Link in, const char *out)
248: {
249: Rep r;
250: Link l;
251: int k;
252:
253: if ((l = LinkFind(out)) == NULL) {
254: Log(LG_REP, ("[%s] Can't find link \"%s\"", in->name, out));
255: return (-1);
256: }
257: if (PhysIsBusy(l)) {
258: Log(LG_REP, ("[%s] Link \"%s\" is busy", in->name, out));
259: return (-1);
260: }
261: if (l->tmpl)
262: l = LinkInst(l, NULL, 0, 0);
263: if (!l) {
264: Log(LG_REP, ("[%s] Can't create link \"%s\"", in->name, out));
265: return (-1);
266: }
267:
268: /* Create a new repeater structure */
269: r = Malloc(MB_REP, sizeof(*r));
270: snprintf(r->name, sizeof(r->name), "R-%s", in->name);
271: r->csock = -1;
272:
273: /* Add repeater to the list of repeaters and make it the current active repeater */
274: for (k = 0; k < gNumReps && gReps[k] != NULL; k++);
275: if (k == gNumReps) /* add a new repeater pointer */
276: LengthenArray(&gReps, sizeof(*gReps), &gNumReps, MB_REP);
277: r->id = k;
278: gReps[k] = r;
279: REF(r);
280:
281: /* Join all part */
282: r->links[0] = in;
283: r->links[1] = l;
284: in->rep = r;
285: l->rep = r;
286:
287: /* Done */
288: return(0);
289: }
290:
291: /*
292: * RepShutdown()
293: */
294:
295: void
296: RepShutdown(Rep r)
297: {
298: int k;
299:
300: gReps[r->id] = NULL;
301:
302: Log(LG_REP, ("[%s] Rep: Shutdown", r->name));
303: for (k = 0; k < 2; k++) {
304: Link l;
305: if ((l = r->links[k]) != NULL)
306: if (!l->stay)
307: LinkShutdown(l);
308: }
309:
310: if (r->csock > 0 && r->node_id) {
311: char path[NG_PATHSIZ];
312:
313: snprintf(path, sizeof(path), "[%x]:", r->node_id);
314: NgFuncShutdownNode(r->csock, r->name, path);
315: r->node_id = 0;
316: close(r->csock);
317: r->csock = -1;
318: }
319: r->dead = 1;
320: UNREF(r);
321: }
322:
323: /*
324: * RepStat()
325: *
326: * Show state of a repeater
327: */
328:
329: int
330: RepStat(Context ctx, int ac, char *av[], void *arg)
331: {
332: Rep r;
333:
334: /* Find repeater they're talking about */
335: switch (ac) {
336: case 0:
337: r = ctx->rep;
338: break;
339: case 1:
340: if ((r = RepFind(av[0])) == NULL)
341: Error("Repeater \"%s\" not defined.", av[0]);
342: break;
343: default:
344: return(-1);
345: }
346:
347: /* Show stuff about the repeater */
348: Printf("Repeater %s:\r\n", r->name);
349: Printf("\tLinks : ");
350: RepShowLinks(ctx, r);
351:
352: return(0);
353: }
354:
355: /*
356: * RepShowLinks()
357: */
358:
359: static void
360: RepShowLinks(Context ctx, Rep r)
361: {
362: int j;
363:
364: for (j = 0; j < 2; j++) {
365: if (r->links[j]) {
366: Printf("%s[%s/%s] ", r->links[j]->name, r->links[j]->type->name,
367: gPhysStateNames[r->links[j]->state]);
368: }
369: }
370: Printf("\r\n");
371: }
372:
373: /*
374: * RepFind()
375: *
376: * Find a repeater structure
377: */
378:
379: Rep
380: RepFind(char *name)
381: {
382: int k;
383:
384: for (k = 0;
385: k < gNumReps && (!gReps[k] || strcmp(gReps[k]->name, name));
386: k++);
387: return((k < gNumReps) ? gReps[k] : NULL);
388: }
389:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>