Annotation of embedaddon/mpd/src/rep.c, revision 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>