Annotation of embedaddon/mpd/src/rep.c, revision 1.1.1.2
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
1.1.1.2 ! misho 206: RepCommand(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 207: {
208: Rep r;
209: int k;
210:
1.1.1.2 ! misho 211: (void)arg;
! 212:
1.1 misho 213: if (ac > 1)
214: return (-1);
215:
216: if (ac == 0) {
217: Printf("Defined repeaters:\r\n");
218: for (k = 0; k < gNumReps; k++) {
219: if ((r = gReps[k]) != NULL) {
220: Printf("\t%-15s%s %s\n",
221: r->name, r->links[0]->name, r->links[1]->name);
222: }
223: }
224: return (0);
225: }
226:
227: if ((r = RepFind(av[0])) == NULL) {
228: RESETREF(ctx->rep, NULL);
229: RESETREF(ctx->bund, NULL);
230: RESETREF(ctx->lnk, NULL);
231: Error("Repeater \"%s\" not defined.", av[0]);
232: }
233:
234: /* Change repeater, and link also if needed */
235: RESETREF(ctx->rep, r);
236: RESETREF(ctx->bund, NULL);
237: RESETREF(ctx->lnk, r->links[0]);
238:
239: return(0);
240: }
241:
242: /*
243: * RepCreate()
244: *
245: * Create a new repeater.
246: */
247:
248: int
249: RepCreate(Link in, const char *out)
250: {
251: Rep r;
252: Link l;
253: int k;
254:
255: if ((l = LinkFind(out)) == NULL) {
256: Log(LG_REP, ("[%s] Can't find link \"%s\"", in->name, out));
257: return (-1);
258: }
259: if (PhysIsBusy(l)) {
260: Log(LG_REP, ("[%s] Link \"%s\" is busy", in->name, out));
261: return (-1);
262: }
263: if (l->tmpl)
264: l = LinkInst(l, NULL, 0, 0);
265: if (!l) {
266: Log(LG_REP, ("[%s] Can't create link \"%s\"", in->name, out));
267: return (-1);
268: }
269:
270: /* Create a new repeater structure */
271: r = Malloc(MB_REP, sizeof(*r));
272: snprintf(r->name, sizeof(r->name), "R-%s", in->name);
273: r->csock = -1;
274:
275: /* Add repeater to the list of repeaters and make it the current active repeater */
276: for (k = 0; k < gNumReps && gReps[k] != NULL; k++);
277: if (k == gNumReps) /* add a new repeater pointer */
278: LengthenArray(&gReps, sizeof(*gReps), &gNumReps, MB_REP);
279: r->id = k;
280: gReps[k] = r;
281: REF(r);
282:
283: /* Join all part */
284: r->links[0] = in;
285: r->links[1] = l;
286: in->rep = r;
287: l->rep = r;
288:
289: /* Done */
290: return(0);
291: }
292:
293: /*
294: * RepShutdown()
295: */
296:
297: void
298: RepShutdown(Rep r)
299: {
300: int k;
301:
302: gReps[r->id] = NULL;
303:
304: Log(LG_REP, ("[%s] Rep: Shutdown", r->name));
305: for (k = 0; k < 2; k++) {
306: Link l;
307: if ((l = r->links[k]) != NULL)
308: if (!l->stay)
309: LinkShutdown(l);
310: }
311:
312: if (r->csock > 0 && r->node_id) {
313: char path[NG_PATHSIZ];
314:
315: snprintf(path, sizeof(path), "[%x]:", r->node_id);
316: NgFuncShutdownNode(r->csock, r->name, path);
317: r->node_id = 0;
318: close(r->csock);
319: r->csock = -1;
320: }
321: r->dead = 1;
322: UNREF(r);
323: }
324:
325: /*
326: * RepStat()
327: *
328: * Show state of a repeater
329: */
330:
331: int
1.1.1.2 ! misho 332: RepStat(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 333: {
334: Rep r;
335:
1.1.1.2 ! misho 336: (void)arg;
! 337:
1.1 misho 338: /* Find repeater they're talking about */
339: switch (ac) {
340: case 0:
341: r = ctx->rep;
342: break;
343: case 1:
344: if ((r = RepFind(av[0])) == NULL)
345: Error("Repeater \"%s\" not defined.", av[0]);
346: break;
347: default:
348: return(-1);
349: }
350:
351: /* Show stuff about the repeater */
352: Printf("Repeater %s:\r\n", r->name);
353: Printf("\tLinks : ");
354: RepShowLinks(ctx, r);
355:
356: return(0);
357: }
358:
359: /*
360: * RepShowLinks()
361: */
362:
363: static void
364: RepShowLinks(Context ctx, Rep r)
365: {
366: int j;
367:
368: for (j = 0; j < 2; j++) {
369: if (r->links[j]) {
370: Printf("%s[%s/%s] ", r->links[j]->name, r->links[j]->type->name,
371: gPhysStateNames[r->links[j]->state]);
372: }
373: }
374: Printf("\r\n");
375: }
376:
377: /*
378: * RepFind()
379: *
380: * Find a repeater structure
381: */
382:
383: Rep
1.1.1.2 ! misho 384: RepFind(const char *name)
1.1 misho 385: {
386: int k;
387:
388: for (k = 0;
389: k < gNumReps && (!gReps[k] || strcmp(gReps[k]->name, name));
390: k++);
391: return((k < gNumReps) ? gReps[k] : NULL);
392: }
393:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>