File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / rep.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 08:44:29 2013 UTC (11 years ago) by misho
Branches: mpd, MAIN
CVS tags: v5_8p7, v5_8p1_cross, v5_8p1, v5_8, v5_7p0, v5_7, v5_6, HEAD
5.7

    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>