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>