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>