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>