Annotation of researchv10no/ipc/mgrs/tcpmgr/dial.c, revision 1.1

1.1     ! root        1: #include <sys/types.h>
        !             2: #include <stdio.h>
        !             3: #include <signal.h>
        !             4: #include <errno.h>
        !             5: #include <ipc.h>
        !             6: #include <sys/filio.h>
        !             7: #include <sys/inio.h>
        !             8: #include <sys/inet/tcp_user.h>
        !             9: #include <sys/inet/tcp_timer.h>
        !            10: #include <sys/inet/tcp_var.h>
        !            11: #include <libc.h>
        !            12: #include <ctype.h>
        !            13: #include "defs.h"
        !            14: 
        !            15: #define CSPORT 1
        !            16: 
        !            17: #define CALLIN 0
        !            18: #define CALLOUT 1
        !            19: #define ANNOUNCE 2
        !            20: #define CALLINCS 3
        !            21: 
        !            22: /* imported */
        !            23: extern char *in_ntoa();
        !            24: extern in_addr in_address();
        !            25: extern int tcp_connect();
        !            26: extern int tcp_accept();
        !            27: extern int tcp_listen();
        !            28: extern char *in_host();
        !            29: extern in_addr in_aton();
        !            30: extern int rmesg_ld;
        !            31: extern char *mydomain;
        !            32: 
        !            33: Qset *domainorder();
        !            34: 
        !            35: /* dial a service on the internet - try first via cs, then direct */
        !            36: int
        !            37: net_dial(ip)
        !            38:        ipcinfo *ip;
        !            39: {
        !            40:        char *service;
        !            41:        int lport, fport;
        !            42:        int i, n, fd;
        !            43:        char *fields[16];
        !            44:        Qset *sp, *tsp;
        !            45:        Qtuple *tp;
        !            46:        int tries;
        !            47:        char *dom, *in, *firstdom;
        !            48:        char dname[256];
        !            49:        int gooddom;
        !            50: 
        !            51:        lport = 0;
        !            52:        tries = 0;
        !            53: 
        !            54:        /* break parameter list */
        !            55:        n = breakparams(ip, fields, 16);
        !            56:        for(i=0; i<n; i++){
        !            57:                if(strncmp(fields[i], "port=", 5)==0){
        !            58:                        lport=atoi(fields[i]+5);
        !            59:                        if(lport<1024 && ip->uid!=0)
        !            60:                            return ABORT(ENOENT, "illegal port", NULLINFO);
        !            61:                        break;
        !            62:                }
        !            63:        }
        !            64: 
        !            65:        /* get the service */
        !            66:        service = strchr(ip->name, '!');
        !            67:        if (service != NULL)
        !            68:                *service++ = '\0';
        !            69:        else
        !            70:                return ABORT(ENOENT, "unassigned service", NULLINFO);
        !            71:        fport = fstotcp(service);
        !            72: 
        !            73:        /* look up the system */
        !            74:        strcpy(dname, ip->name);
        !            75:        strcat(dname, ",dom");
        !            76:        sp = qset(dname, (char *)NULL);
        !            77:        if (sp==NULL) {
        !            78:                sp = qset(ip->name, (char *)NULL);
        !            79:                if(sp==NULL){
        !            80:                        /* no such system - assume we have an ip number */
        !            81:                        if(isdigit(*ip->name))
        !            82:                                return dialip(ip->name, lport, fport, fields, n,
        !            83:                                                 ip, service);
        !            84:                        else
        !            85:                                return ABORT(ENOENT, "unassigned destination",
        !            86:                                 NULLINFO);
        !            87:                }
        !            88:        }
        !            89: 
        !            90:        /*  call each INET address in succession.  If a domain name is
        !            91:         *  encountered, try no entry of another doain name.
        !            92:         */
        !            93:        firstdom = NULL;
        !            94:        for(tsp=sp; tsp; tsp=tsp->next) {
        !            95:                gooddom = 0;
        !            96:                dom = in = NULL;
        !            97:                for(tp=tsp->this; tp; tp=tp->next)
        !            98:                        if(tp->type && strcmp(tp->type, "in")==0)
        !            99:                                in = tp->value;
        !           100:                        else if(tp->type && strcmp(tp->type, "dom")==0){
        !           101:                                dom = tp->value;
        !           102:                                if(firstdom==NULL) {
        !           103:                                        firstdom = dom;
        !           104:                                        gooddom = 1;
        !           105:                                } else {
        !           106:                                        if(strcmp(firstdom, dom)==0)
        !           107:                                                gooddom = 1;
        !           108:                                }
        !           109:                        }
        !           110:                if(in){
        !           111:                        if(!gooddom && dom)
        !           112:                                continue;
        !           113:                        tries++;
        !           114:                        fd = dialip(in, lport, fport, fields, n, ip,
        !           115:                                        service);
        !           116:                        if(fd>=0){
        !           117:                                freeQset(sp);
        !           118:                                return(fd);
        !           119:                        }
        !           120:                }
        !           121:        }
        !           122: 
        !           123:        /* none worked */
        !           124:        freeQset(sp);
        !           125:        if(tries)
        !           126:                return ABORT(errno, errstr, NULLINFO);
        !           127:        else
        !           128:                return ABORT(ENOENT, "unassigned destination", NULLINFO);
        !           129: }
        !           130: 
        !           131: /*
        !           132:  *  order tuples relative to a domain address
        !           133:  */
        !           134: int
        !           135: matchval(np, dp)
        !           136:        char *np;
        !           137:        char *dp;
        !           138: {
        !           139:        char *cnp, *cdp;
        !           140:        int rv = 0;
        !           141: 
        !           142:        cnp = np+strlen(np);
        !           143:        cdp = dp+strlen(dp);
        !           144:        do {
        !           145:                while(--cdp>dp)
        !           146:                        if(*cdp=='.')
        !           147:                                break;
        !           148:                while(--cnp>np)
        !           149:                        if(*cnp=='.')
        !           150:                                break;
        !           151:                if(strcmp(cdp, cnp)!=0)
        !           152:                        break;
        !           153:                rv++;
        !           154:        } while(cdp>dp);
        !           155:        return rv;
        !           156: }
        !           157: 
        !           158: dialalarm()
        !           159: {
        !           160: }
        !           161: 
        !           162: /*
        !           163:  *  dial one ip address
        !           164:  *
        !           165:  *  Use a port < 1024 if:
        !           166:  *     a) the caller is root
        !           167:  *     b) we are calling the connection server
        !           168:  *     c) the caller requests us to perform bsd authentication for him
        !           169:  */
        !           170: dialip(number, lport, fport, fields, n, ip, service)
        !           171:        char *number;
        !           172:        int lport, fport;
        !           173:        char *fields[];
        !           174:        int n;
        !           175:        ipcinfo *ip;
        !           176:        char *service;
        !           177: {
        !           178:        struct tcpuser tu;
        !           179:        in_addr faddr;
        !           180:        int fd;
        !           181:        int (*oldsig)();
        !           182:        int ba;
        !           183: 
        !           184:        logevent("trying: %s\n", number);
        !           185:        faddr = in_aton(number);
        !           186:        if(faddr==INADDR_ANY)
        !           187:                return ABORT(ENOENT, "unassigned destination", NULLINFO);
        !           188:        ba = bsdauth(fields, n);
        !           189: 
        !           190:        /* get a channel for the connection */
        !           191:        fd = tcp_sock();
        !           192:        if (fd < 0)
        !           193:                return ABORT(EBUSY, "out of output channels", NULLINFO);
        !           194: 
        !           195:        /*
        !           196:         *  connect to the remote connection server if there is not a well known
        !           197:         *  port for this service.
        !           198:         */
        !           199:        if(fport<=0){
        !           200:                tu.laddr = INADDR_ANY;
        !           201:                tu.lport = 0;
        !           202:                tu.faddr = faddr;
        !           203:                tu.fport = CSPORT;
        !           204:                tcpoptions(&tu, fields, n, ba, ip);
        !           205:                errstr = "destination not answering";
        !           206: 
        !           207:                /*
        !           208:                 *  give connection servers 5 seconds to answer (if it can)
        !           209:                 */
        !           210:                oldsig = signal(SIGALRM, dialalarm);
        !           211:                alarm(5);
        !           212:                if (tcp_connect(fd, &tu)>=0) {
        !           213:                        alarm(0);
        !           214:                        signal(SIGALRM, oldsig);
        !           215: 
        !           216:                        /*
        !           217:                         *  send the request
        !           218:                         */
        !           219:                        ip->name = service;
        !           220:                        if (_info_write(fd, ip)==0)
        !           221:                                if (_reply_read(fd)==0 && errno==0) {
        !           222:                                        condition(fd, fields, n, ip->user);
        !           223:                                        filloutnames(&tu, ip, CALLOUT);
        !           224:                                        return fd;
        !           225:                                }
        !           226:                }
        !           227:                alarm(0);
        !           228:                signal(SIGALRM, oldsig);
        !           229:                close(fd);
        !           230:                return -1;
        !           231:        } else {
        !           232: 
        !           233:                /*
        !           234:                 *   connect to the well known port
        !           235:                 */
        !           236:                fd = tcp_sock();
        !           237:                if (fd < 0)
        !           238:                        return ABORT(EBUSY, "out of output channels", NULLINFO);
        !           239:                tu.laddr = INADDR_ANY;
        !           240:                tu.lport = lport;
        !           241:                tu.faddr = faddr;
        !           242:                tu.fport = fport;
        !           243:                tcpoptions(&tu, fields, n, ba, ip);
        !           244:                if (tu.fport<=0) {
        !           245:                        close(fd);
        !           246:                        return ABORT(ENOENT, "unknown service", NULLINFO);
        !           247:                }
        !           248:        
        !           249:                /*
        !           250:                 *  give other system 15 seconds to answer (if it can)
        !           251:                 */
        !           252:                oldsig = signal(SIGALRM, dialalarm);
        !           253:                alarm(15);
        !           254:                if (tcp_connect(fd, &tu)<0) {
        !           255:                        alarm(0);
        !           256:                        signal(SIGALRM, oldsig);
        !           257:                        close(fd);
        !           258:                        return -1;
        !           259:                }
        !           260:                alarm(0);
        !           261:                signal(SIGALRM, oldsig);
        !           262:                condition(fd, fields, n, ip->user);
        !           263:                filloutnames(&tu, ip, CALLOUT);
        !           264:                return fd;
        !           265:        }
        !           266: }
        !           267: 
        !           268: /* return true if bsd authentication is requested */
        !           269: bsdauth(fields, n)
        !           270:        char *fields[];
        !           271:        int n;
        !           272: {
        !           273:        int i;
        !           274: 
        !           275:        for (i=0; i<n && fields[i]; i++)
        !           276:                if (strcmp(fields[i], "bsdauth")==0)
        !           277:                        return 1;
        !           278:        return 0;
        !           279: }
        !           280: 
        !           281: /* create options */
        !           282: tcpoptions(tp, fields, n, bsdauth, ip)
        !           283:        struct tcpuser *tp;
        !           284:        char *fields[];
        !           285:        ipcinfo *ip;
        !           286: {
        !           287:        int i;
        !           288: 
        !           289:        if(bsdauth)
        !           290:                tp->param = SO_TRUSTED;
        !           291:        else
        !           292:                tp->param = ip->uid==0 ? SO_TRUSTED : 0;
        !           293: 
        !           294:        for (i=0; i<n && fields[i]; i++) {
        !           295:                if (strcmp(fields[i], "keepalive")==0)
        !           296:                        tp->param |= SO_KEEPALIVE;
        !           297:        }
        !           298: }
        !           299: 
        !           300: /* condition the connection as requested */
        !           301: condition(fd, fields, n, user)
        !           302:        int fd;
        !           303:        char *fields[];
        !           304:        char *user;
        !           305: {
        !           306:        int i;
        !           307:        int dohup=0;
        !           308:        int dobsd=0;
        !           309:        int domesg=0;
        !           310: 
        !           311:        for (i=0; i<n && fields[i]; i++) {
        !           312:                if (strcmp(fields[i], "hup")==0)
        !           313:                        dohup = 1;
        !           314:                if (strcmp(fields[i], "delim")==0)
        !           315:                        domesg = 1;
        !           316:                if (strcmp(fields[i], "bsdauth")==0){
        !           317:                        dobsd = 1;
        !           318:                }
        !           319:        }
        !           320:        if (dobsd){
        !           321:                if(!user)
        !           322:                        user = "_unknown_";
        !           323:                write(fd, "", 1);
        !           324:                write(fd, user, strlen(user)+1);
        !           325:                write(fd, user, strlen(user)+1);
        !           326:        }
        !           327:        if (dohup){
        !           328:                ioctl(fd, TCPIOHUP, 0);
        !           329:        }
        !           330:        if (domesg){
        !           331:                ioctl(fd, FIOPUSHLD, &rmesg_ld);
        !           332:        }
        !           333: }
        !           334: 
        !           335: /* get the local name out of the connection info */
        !           336: filloutnames(tp, ip, type)
        !           337:        struct tcpuser *tp;
        !           338:        ipcinfo *ip;
        !           339: {
        !           340:        static stretch newipcname;
        !           341:        static stretch fmachine;
        !           342:        static stretch lmachine;
        !           343:        static stretch fportname;
        !           344:        static stretch lportname;
        !           345:        char *fields[16];
        !           346: 
        !           347:        _strcat(&lmachine, in_ntoa(tp->laddr), (char *)0, (char *)0);
        !           348:        _strcat(&lportname, "xxxxxxxxxx", (char *)0, (char *)0);
        !           349:        switch (type) {
        !           350:        case CALLINCS:
        !           351:                /*
        !           352:                 *  a call from the network via connection server
        !           353:                 */
        !           354:                sprintf(lportname.ptr, "tcp.%d", tp->lport);
        !           355:                _strcat(&fmachine, in_host(tp->faddr), (char *)0, (char *)0);
        !           356:                ip->myname = lmachine.ptr;
        !           357:                ip->machine = fmachine.ptr;
        !           358:                break;
        !           359:        case CALLIN:
        !           360:                /*
        !           361:                 *  a call from the network
        !           362:                 */
        !           363:                sprintf(lportname.ptr, "tcp.%d", tp->lport);
        !           364:                _strcat(&fmachine, in_host(tp->faddr), (char *)0, (char *)0);
        !           365:                ip->myname = lmachine.ptr;
        !           366:                ip->machine = fmachine.ptr;
        !           367:                break;
        !           368:        case CALLOUT:
        !           369:                /*
        !           370:                 *  a call to the network
        !           371:                 */
        !           372:                sprintf(lportname.ptr, "%d", tp->lport);
        !           373:                _strcat(&fmachine, in_ntoa(tp->faddr), (char *)0, (char *)0);
        !           374:                _strcat(&fportname, "xxxxxxxxxx", (char *)0, (char *)0);
        !           375:                sprintf(fportname.ptr, "%d", tp->fport);
        !           376:                ip->myname = fmachine.ptr;
        !           377:                ip->name = fportname.ptr;
        !           378:                ip->machine = lmachine.ptr;
        !           379:                break;
        !           380:        case ANNOUNCE:
        !           381:                /*
        !           382:                 * an announcement
        !           383:                 */
        !           384:                sprintf(lportname.ptr, "%d", tp->lport);
        !           385:                ip->myname = lmachine.ptr;
        !           386:                ip->name = lportname.ptr;
        !           387:                ip->machine = lmachine.ptr;
        !           388:                break;
        !           389:        }
        !           390:        _strcat(&newipcname, lmachine.ptr, "!", lportname.ptr);
        !           391:        ipcname = newipcname.ptr;
        !           392: }
        !           393: 
        !           394: /* break up parameter list */
        !           395: breakparams(ip, fields, n)
        !           396:        ipcinfo *ip;
        !           397:        char *fields[];
        !           398:        int n;
        !           399: {
        !           400:        static stretch param;
        !           401: 
        !           402:        if (*ip->param){
        !           403:                _strcat(&param, ip->param, (char *)0, (char *)0);
        !           404:                setfields(" \t");
        !           405:                n = getmfields(param.ptr, fields, n);
        !           406:        } else
        !           407:                n = 0;
        !           408: 
        !           409:        return n;
        !           410: }
        !           411: 
        !           412: /* announce onto the internet */
        !           413: int
        !           414: net_announce(ip)
        !           415:        ipcinfo *ip;
        !           416: {
        !           417:        int fd, n;
        !           418:        struct tcpuser tu;
        !           419:        static stretch dest;
        !           420:        char *fields[4];
        !           421:        in_addr myaddr;
        !           422:        int port;
        !           423: 
        !           424:        /*
        !           425:         *  break the address into host and service
        !           426:         */
        !           427:        _strcat(&dest, ip->name, (char *)0, (char *)0);
        !           428:        setfields("!");
        !           429:        n = getmfields(dest.ptr, fields, 4);
        !           430:        switch(n){
        !           431:        case 0:
        !           432:                /* accept all calls not specificly asked for */
        !           433:                fields[0] = "";
        !           434:                fields[1] = "";
        !           435:                break;
        !           436:        case 1:
        !           437:                /* accept specified address */
        !           438:                fields[1] = "";
        !           439:                break;
        !           440:        case 2:
        !           441:                break;
        !           442:        default:
        !           443:                return ABORT(ENOENT, "illegal address", NULLINFO);
        !           444:        }
        !           445: 
        !           446:        /*
        !           447:         *  no address means listen for calls to any address
        !           448:         */
        !           449:        if (*fields[0]) {
        !           450:                myaddr = in_address(fields[0]);
        !           451:                if(myaddr==0)
        !           452:                        return ABORT(ENOENT, "illegal address", NULLINFO);
        !           453:        } else
        !           454:                myaddr = INADDR_ANY;
        !           455: 
        !           456:        /*
        !           457:         *  no port means listen for calls to any port.  port '*' means
        !           458:         *  pick me a port to listen on (returned in ipcname)
        !           459:         */
        !           460:        if (*fields[1]){
        !           461:                if (strcmp(fields[1], "*")==0)
        !           462:                        port = 0;
        !           463:                else {
        !           464:                        port = atoi(fields[1]);
        !           465:                        if(port<1024 && ip->uid!=0)
        !           466:                                return ABORT(ENOENT, "illegal port", NULLINFO);
        !           467:                }
        !           468:        } else
        !           469:                port = TCPPORT_ANY;
        !           470: 
        !           471:        /* perform the announcement */
        !           472:        fd = tcp_sock();
        !           473:        if (fd < 0)
        !           474:                return ABORT(EBUSY, "no more output channels", NULLINFO);
        !           475:        tu.lport = port;
        !           476:        tu.laddr = myaddr;
        !           477:        tu.fport = 0;
        !           478:        tu.faddr = 0;
        !           479:        tu.param = ip->uid==0 ? SO_TRUSTED : 0;
        !           480:        if (tcp_listen(fd, &tu)<0) {
        !           481:                close(fd);
        !           482:                return ABORT(EEXIST, "server already exists", NULLINFO);
        !           483:        }
        !           484:        filloutnames(&tu, ip, ANNOUNCE);
        !           485:        return fd;
        !           486: }
        !           487: 
        !           488: /* listen for a call in */
        !           489: ipcinfo *
        !           490: net_listen(fd)
        !           491:        int fd;
        !           492: {
        !           493:        static ipcinfo info;
        !           494:        static char myname[PATHLEN];
        !           495:        static char name[PATHLEN];
        !           496:        static char machine[PATHLEN];
        !           497:        struct tcpuser tu;
        !           498:        char param[128];
        !           499:        char *fields[16];
        !           500:        int n;
        !           501:        extern char *tcptofs();
        !           502: 
        !           503:        info.flags = 0;
        !           504:        for(;;) {
        !           505:                tu.param = 0;
        !           506:                if ((fd = tcp_accept(fd, &tu))<0) {
        !           507:                        logevent("listen: tcp_accept failed-- errno %d\n", errno);
        !           508:                        return NULL;
        !           509:                }
        !           510:                if (tu.lport == CSPORT) {
        !           511:                        if (tu.fport > 1023)
        !           512:                                info.uid = info.gid = -1;
        !           513:                        else
        !           514:                                info.uid = info.gid = 0;
        !           515:                        info.user = "_unknown_";
        !           516:                        if (_info_read(fd, &info)<0) {
        !           517:                                logevent("listen: info_read failed -- errno %d\n", errno);
        !           518:                                close(fd);
        !           519:                                return (ipcinfo *)NULL;
        !           520:                        }
        !           521:                        info.flags |= IPC_HANDOFF;
        !           522: 
        !           523:                        /* break parameters */
        !           524:                        n = breakparams(&info, fields, 16);
        !           525:                        condition(fd, fields, n, (char *)0);
        !           526:                        filloutnames(&tu, &info, CALLINCS);
        !           527:                } else {
        !           528:                        info.user = tu.fport>=1024 ? "_unknown_" : "root";
        !           529:                        info.param = "";
        !           530:                        strcpy(name, tcptofs(tu.lport));
        !           531:                        info.name = name;
        !           532:                        filloutnames(&tu, &info, CALLIN);
        !           533:                }
        !           534:                info.flags |= IPC_OPEN;
        !           535:                info.rfd = fd;
        !           536:                info.cfd = -1;
        !           537:                return &info;
        !           538:        }
        !           539: }
        !           540: 
        !           541: /* accept a call */
        !           542: void
        !           543: net_accept(ip)
        !           544:        ipcinfo *ip;
        !           545: {
        !           546:        USE(ip);
        !           547: }
        !           548: 
        !           549: /* reject a call - null if a non-cs call */
        !           550: void
        !           551: net_reject(ip, no, str)
        !           552:        ipcinfo *ip;
        !           553:        int no;
        !           554:        char *str;
        !           555: {
        !           556:        if (ip->flags&IPC_HANDOFF && ip->rfd>=0)
        !           557:                _reply_write(ip->rfd, no, str);
        !           558:        if (ip->rfd>=0) {
        !           559:                close(ip->rfd);
        !           560:                ip->rfd = -1;
        !           561:        }
        !           562: }
        !           563: 
        !           564: int
        !           565: net_redial(ip)
        !           566:        ipcinfo *ip;
        !           567: {
        !           568:        return -1;
        !           569: }
        !           570: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.