File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / rep.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:39:23 2021 UTC (4 years ago) by misho
Branches: mpd, MAIN
CVS tags: v5_9p16, v5_9, HEAD
mpd 5.9

    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, const char *const av[], const void *arg)
  207: {
  208:     Rep	r;
  209:     int	k;
  210: 
  211:     (void)arg;
  212: 
  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
  332: RepStat(Context ctx, int ac, const char *const av[], const void *arg)
  333: {
  334:     Rep	r;
  335: 
  336:     (void)arg;
  337: 
  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
  384: RepFind(const char *name)
  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>