Annotation of researchv10no/sys/inet/tcp_device.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * tcp_device.c
                      3:  */
                      4: 
                      5: #include "sys/param.h"
                      6: #include "sys/stream.h"
                      7: #include "sys/inio.h"
                      8: #include "sys/ttyio.h"
                      9: #include "sys/conf.h"
                     10: #include "sys/user.h"
                     11: #include "sys/inet/in.h"
                     12: #include "sys/inet/ip_var.h"
                     13: #include "sys/inet/tcp.h"
                     14: #include "sys/inet/tcp_timer.h"
                     15: #include "sys/inet/tcp_seq.h"
                     16: #include "sys/inet/tcp_var.h"
                     17: #include "sys/inet/tcpip.h"
                     18: #include "sys/inet/tcp_user.h"
                     19: #include "sys/inet/tcp_fsm.h"
                     20: 
                     21: extern int tcp_busy;   /* set to discourage timers & ensuing panics */
                     22: extern int tcp_maxseg;
                     23: 
                     24: long   tcpdopen();
                     25: int    tcpdclose(), tcpdput();
                     26: int    tcpdosrv(), tcpdisrv();
                     27: static struct qinit tcpdrinit = { noput, tcpdisrv, tcpdopen, tcpdclose, 2048, 64 };
                     28:        struct qinit tcpdwinit = { tcpdput, tcpdosrv, tcpdopen, tcpdclose, 2048, 64};
                     29: struct streamtab tcpdinfo = { &tcpdrinit, &tcpdwinit };
                     30: 
                     31: struct cdevsw tcpcdev = cstrinit(&tcpdinfo);
                     32: 
                     33: extern int tcpcnt;
                     34: extern struct tcpcb tcpcb[];
                     35: 
                     36: long
                     37: tcpdopen(q, dev)
                     38: register struct queue *q;
                     39: dev_t dev;
                     40: {
                     41:        struct tcpcb *tp;
                     42: 
                     43:        dev = minor(dev);
                     44:        if(dev >= tcpcnt)
                     45:                return(0);
                     46:        tp = &tcpcb[dev];
                     47:        if(dev&01){
                     48:                /* outgoing channel */
                     49:                /*
                     50:                 *  disallow if active
                     51:                 */
                     52:                if(tp->t_state != TCPS_CLOSED)
                     53:                        return(0);
                     54:                /*
                     55:                 *  only one opener at a time for outgoing channels
                     56:                 */
                     57:                if(q->ptr)
                     58:                        return(0);
                     59:        } else {
                     60:                /* incoming channel */
                     61:                /*
                     62:                 *  disallow if inactive
                     63:                 */
                     64:                if(tp->t_state == TCPS_CLOSED) {
                     65: printf("tcp%d closed\n", dev);
                     66:                        return(0);
                     67:                }
                     68:                /*
                     69:                 *  disallow if it's not open or waiting to be opened
                     70:                 */
                     71:                if((tp->so_state&(SS_OPEN|SS_PLEASEOPEN))==0) {
                     72: printf("tcp%d state %x\n", dev, tp->so_state);
                     73:                        return(0);
                     74:                }
                     75:                /*
                     76:                 *  if already open, just accept
                     77:                 */
                     78:                if(q->ptr)
                     79:                        return(1);
                     80:        }
                     81:        tcp_busy++;
                     82:        if((tp->so_state & SS_PLEASEOPEN) == 0){
                     83:                tp->so_rcount = tp->so_wcount = tp->so_options = 0;
                     84:                tp->so_laddr = tp->so_faddr = (in_addr)0;
                     85:                tp->so_lport = tp->so_fport = (tcp_port)0;
                     86:                tp->so_oobmark = tp->so_delimcnt = 0;
                     87:                tp->so_head = (struct tcpcb *)0;
                     88:                tp->so_state = SS_WAITING;
                     89:                tp->t_maxseg = TCP_DEFMAXSEG;   /* until changed by other end */
                     90:        }
                     91:        tp->so_state |= SS_OPEN;
                     92:        tp->so_dev = dev;
                     93:        tp->so_rq = q;
                     94:        tp->so_wq = WR(q);
                     95:        q->ptr = (caddr_t)tp;
                     96:        WR(q)->flag |= QBIGB;
                     97:        WR(q)->ptr = (caddr_t)tp;
                     98:        --tcp_busy;
                     99:        if(tp->so_state & SS_PLEASEOPEN){
                    100:                tp->so_state &= ~SS_PLEASEOPEN;
                    101:                qenable(WR(q));         /* to force out rcv wnd update */
                    102:        }
                    103:        return(1);
                    104: }
                    105: 
                    106: tcpdclose(q)
                    107: register struct queue *q;
                    108: {
                    109:        struct tcpcb *tp;
                    110: 
                    111:        tp = (struct tcpcb *)q->ptr;
                    112:        tcp_busy++;
                    113:        if(tp == 0){
                    114:                --tcp_busy;
                    115:                return;
                    116:        }
                    117:        tp->so_state &= ~(SS_OPEN|SS_WAITING);
                    118:        tp->so_rq = tp->so_wq = (struct queue *) 0;
                    119:        tp->so_wcount = tp->so_rcount = 0;
                    120:        if(tp->t_state > TCPS_LISTEN)
                    121:                tcp_disconnect(tp);
                    122:        else
                    123:                tcp_close(tp);
                    124:        --tcp_busy;
                    125: }
                    126: 
                    127: tcpdput(q, bp)
                    128: register struct queue *q;
                    129: register struct block *bp;
                    130: {
                    131:        int s, x;
                    132:        struct tcpcb *tp;
                    133:        struct block *nbp;
                    134:        struct foo {
                    135:                int com;
                    136:                struct tcpuser rep;
                    137:        };
                    138:        struct foo *fp;
                    139: 
                    140:        tp = (struct tcpcb *)q->ptr;
                    141:        switch(bp->type){
                    142:        case M_IOCTL:
                    143:                bp->type = M_IOCACK;
                    144:                switch(stiocom(bp)){
                    145:                case TIOCSETP:
                    146:                case TIOCSETN:
                    147:                        x = ((struct ttydevb *)stiodata(bp))->ispeed;
                    148:                        bp->wptr = bp->rptr;
                    149:                        bp->type = M_IOCACK;
                    150:                        qreply(q, bp);
                    151:                        if(x == 0)
                    152:                                qpctl(OTHERQ(q), M_HANGUP);
                    153:                        return;
                    154:                case TIOCGETP:
                    155:                        ((struct ttydevb *)stiodata(bp))->ispeed =
                    156:                          ((struct ttydevb *)stiodata(bp))->ospeed = B9600;
                    157:                        break;
                    158:                case TCPGETADDR:
                    159:                        nbp = allocb(sizeof(struct foo));
                    160:                        if (nbp == NULL) {
                    161:                                bp->type = M_IOCNAK;
                    162:                                break;
                    163:                        }
                    164:                        nbp->type = M_IOCACK;
                    165:                        fp = (struct foo *)nbp->rptr;
                    166:                        fp->com = stiocom(bp);
                    167:                        fp->rep.lport = tp->so_lport;
                    168:                        fp->rep.fport = tp->so_fport;
                    169:                        fp->rep.laddr = tp->so_laddr;
                    170:                        fp->rep.faddr = tp->so_faddr;
                    171:                        nbp->wptr = nbp->rptr + sizeof(struct foo);
                    172:                        freeb(bp);
                    173:                        bp = nbp;
                    174:                        break;
                    175:                case TCPIOHUP:
                    176:                        tp->so_state |= SS_HANGUP;
                    177:                        bp->wptr = bp->rptr;
                    178:                        bp->type = M_IOCACK;
                    179:                        qreply(q, bp);
                    180:                        return;
                    181:                default:
                    182:                        bp->type = M_IOCNAK;
                    183:                }
                    184:                qreply(q, bp);
                    185:                return;
                    186:        case M_DATA:
                    187:                if(socantsendmore(tp)){
                    188:                        freeb(bp);
                    189:                        return;
                    190:                }
                    191:                s = spl6();
                    192:                if (bp->wptr!=bp->rptr)
                    193:                        tp->so_delimcnt = 0;
                    194:                if (bp->class&S_DELIM)
                    195:                        tp->so_delimcnt++;      /* 2 delims are logical EOF */
                    196:                if (bp->wptr==bp->rptr){
                    197:                        freeb(bp);
                    198:                } else {
                    199:                        tp->so_wcount += BLEN(bp);      /* BEFORE the putq */
                    200:                        putq(q, bp);
                    201:                }
                    202:                splx(s);
                    203:                if(tp->so_delimcnt
                    204:                 || (tp->so_options&(SO_ACCEPTCONN|SS_WAITING)) == 0)
                    205:                        qenable(q);
                    206:                break;
                    207:        default:
                    208:                freeb(bp);
                    209:                break;
                    210:        }
                    211: }
                    212: 
                    213: tcpdosrv(q)
                    214: struct queue *q;
                    215: {
                    216:        register struct tcpcb *tp;
                    217: 
                    218:        if((tp = (struct tcpcb *)q->ptr) == 0)
                    219:                return;
                    220:        if (tp->so_state&SS_WCLOSED)
                    221:                return;
                    222:        tcp_busy++;
                    223:        if(tp->so_delimcnt > 1){
                    224:                tp->so_state |= SS_WCLOSED;
                    225:                tp = tcp_usrclosed(tp);
                    226:                if(tp)
                    227:                        tcp_output(tp);
                    228:        } else if ((tp->so_options & SO_ACCEPTCONN) == 0
                    229:               &&  (tp->so_state & SS_WAITING) == 0)
                    230:                tcp_output(tp);
                    231:        else
                    232:                tcpduser(tp);
                    233:        --tcp_busy;
                    234: }
                    235: 
                    236: tcpdrint(bp, tp)
                    237: register struct block *bp;
                    238: register struct tcpcb *tp;
                    239: {
                    240:        register struct block *bp1;
                    241: 
                    242:        if (tp->so_rq == NULL) {
                    243:                printf("tcpdrint but no tp->so_rq\n");
                    244:                bp_free(bp);
                    245:                return -1;
                    246:        }
                    247:        while(bp){
                    248:                bp1 = bp->next;
                    249:                tp->so_rcount += bp->wptr - bp->rptr;
                    250:                if(bp->wptr <= bp->rptr)
                    251:                        freeb(bp);
                    252:                else
                    253:                        putq(tp->so_rq, bp);
                    254:                bp = bp1;
                    255:        }
                    256:        return 0;
                    257: }
                    258: 
                    259: tcpdisrv(q)
                    260: register struct queue *q;
                    261: {
                    262:        register struct tcpcb *tp = (struct tcpcb *)(q->ptr);
                    263:        register struct block *bp;
                    264: 
                    265:        while ((q->next->flag&QFULL) == 0 && (bp = getq(q)) != NULL) {
                    266:                if(bp->type == M_DATA)
                    267:                        tp->so_rcount -= bp->wptr - bp->rptr;
                    268:                if(tp->so_rcount < 0){
                    269:                        printf("so_rcount %d\n", tp->so_rcount);
                    270:                        if(tp->so_state & SS_OPEN)
                    271:                                panic("so_rcount");
                    272:                }
                    273:                (*q->next->qinfo->putp)(q->next, bp);
                    274:        }
                    275:        if(q->count <= q->qinfo->lolimit)
                    276:                qenable(OTHERQ(q));     /* update remote send window */
                    277: }
                    278: 
                    279: /*
                    280:  * here if channel isn't connected yet:
                    281:  * output `data' is a user command
                    282:  * grab all the data written so far,
                    283:  * even though we'll discard the part we don't use
                    284:  */
                    285: tcpduser(tp)
                    286: register struct tcpcb *tp;
                    287: {
                    288:        extern struct ipif *ip_ifwithaddr();
                    289:        struct tcpuser *tu;
                    290:        struct block *bp, *tail, *head;
                    291: 
                    292:        tail = head = NULL;
                    293:        while(bp = getq(tp->so_wq)){
                    294:                if(bp->type != M_DATA){
                    295:                        freeb(bp);
                    296:                        continue;
                    297:                }
                    298:                bp->next = NULL;
                    299:                if (head == NULL)
                    300:                        head = bp;
                    301:                else
                    302:                        tail->next = bp;
                    303:                tail = bp;
                    304:        }
                    305:        if(head == NULL)
                    306:                return;
                    307:        tp->so_wcount = 0;
                    308:        bp = head;
                    309:        if(BLEN(bp) < sizeof(struct tcpuser)){
                    310:                bp_free(bp);
                    311:                return;
                    312:        }
                    313: 
                    314:        /*
                    315:         *  tu->code is a request to bind this channel
                    316:         */
                    317:        tu = (struct tcpuser *)bp->rptr;
                    318:        switch(tu->code){
                    319:        case TCPC_CONNECT:
                    320:                if(tp->t_state != TCPS_CLOSED){
                    321:                        tu->code = TCPC_BADDEV;
                    322:                        goto bad;
                    323:                }
                    324:                if (tu->laddr != INADDR_ANY) {
                    325:                        /* has the user specified a legal local address? */
                    326:                        if (ip_ifwithaddr(tu->laddr) == 0) {
                    327:                                tu->code = TCPC_BADLOCAL;
                    328:                                goto bad;
                    329:                        }
                    330:                } else {
                    331:                        /* pick a local address related to the destination */
                    332:                        tu->laddr = ip_hoston(tu->faddr);
                    333:                        if(tu->laddr == INADDR_ANY) {
                    334:                                tu->code = TCPC_NOROUTE;
                    335:                                goto bad;
                    336:                        }
                    337:                }
                    338:                tp->so_options = tu->param & ~SO_ACCEPTCONN;
                    339:                if(tcpcb_bind(tp, tu->laddr, tu->lport)) {
                    340:                        tu->code = TCPC_BOUND;
                    341:                        goto bad;
                    342:                }
                    343:                tp->so_fport = tu->fport;
                    344:                tp->so_faddr = tu->faddr;
                    345:                tcp_template(tp);
                    346:                if(tp->t_template == (struct block *)0) {
                    347:                        printf("no template - ");
                    348:                        tu->code = TCPC_BADDEV;
                    349:                        goto bad;
                    350:                }
                    351:                if (tp->so_options & SO_KEEPALIVE)
                    352:                        tcp_timers(tp, TCPT_KEEP);
                    353:                tp->t_state = TCPS_SYN_SENT;
                    354:                tp->iss = tcp_iss; tcp_iss += TCP_ISSINCR/2;
                    355:                tcp_sendseqinit(tp);
                    356:                tp->so_state &= ~SS_WAITING;
                    357:                tcp_output(tp);
                    358:                break;
                    359:        case TCPC_LISTEN:
                    360:                if(tp->t_state != TCPS_CLOSED){
                    361:                        tu->code = TCPC_BADDEV;
                    362:                        goto bad;
                    363:                }
                    364:                if (tu->laddr != INADDR_ANY) {
                    365:                        /* has the user specified a legal local address? */
                    366:                        if (ip_ifwithaddr(tu->laddr) == 0) {
                    367:                                tu->code = TCPC_BADLOCAL;
                    368:                                goto bad;
                    369:                        }
                    370:                }
                    371:                tp->so_options = tu->param & ~SO_ACCEPTCONN;
                    372:                if(tcpcb_bind(tp, tu->laddr, tu->lport)) {
                    373:                        tu->code = TCPC_BOUND;
                    374:                        goto bad;
                    375:                }
                    376:                tp->t_state = TCPS_LISTEN;
                    377:                tp->so_options |= SO_ACCEPTCONN;
                    378:                tp->so_fport = tu->fport==0 ? TCPPORT_ANY : tu->fport;
                    379:                tp->so_faddr = tu->faddr;
                    380:                tcp_template(tp);
                    381:                if(tp->t_template == 0) {
                    382:                        tu->code = TCPC_BADDEV;
                    383:                        printf("no template - ");
                    384:                        goto bad;
                    385:                }
                    386:                tp->so_state &= ~SS_WAITING;
                    387:                if (tcp_isconnected(tp)<0) {
                    388:                        tu->code = TCPC_BADDEV;
                    389:                        goto bad;
                    390:                }
                    391:                break;
                    392:        default:
                    393:                tu->code = TCPC_SORRY;
                    394:                goto bad;
                    395:        }
                    396:        bp_free(bp);
                    397:        return;
                    398: bad:
                    399:        /*
                    400:         *  send reason for failure back to user.
                    401:         */
                    402:        if(bp->next) {
                    403:                bp_free(bp->next);
                    404:                bp->next = 0;
                    405:        }
                    406:        (*tp->so_rq->next->qinfo->putp)(tp->so_rq->next, bp);
                    407:        tcp_hungup(tp);
                    408: }
                    409: 
                    410: struct tcpcb *
                    411: tcp_disconnect(tp)
                    412: register struct tcpcb *tp;
                    413: {
                    414: 
                    415:        if(tp->t_state < TCPS_ESTABLISHED)
                    416:                tp = tcp_close(tp);
                    417:        else {
                    418:                tp->so_state &= ~SS_PLEASEOPEN;
                    419:                tcp_hungup(tp); /* sends M_HANGUP */
                    420:                tp = tcp_usrclosed(tp);
                    421:                if(tp)
                    422:                        tcp_output(tp);
                    423:        }
                    424:        return(tp);
                    425: }
                    426: 
                    427: struct tcpcb *
                    428: tcp_usrclosed(tp)
                    429: register struct tcpcb *tp;
                    430: {
                    431: 
                    432:        switch(tp->t_state){
                    433: 
                    434:        case TCPS_CLOSED:
                    435:        case TCPS_LISTEN:
                    436:        case TCPS_SYN_SENT:
                    437:                tp->t_state = TCPS_CLOSED;
                    438:                tp = tcp_close(tp);
                    439:                break;
                    440: 
                    441:        case TCPS_SYN_RECEIVED:
                    442:        case TCPS_ESTABLISHED:
                    443:                tp->t_state = TCPS_FIN_WAIT_1;
                    444:                tp->so_options |= SO_KEEPALIVE;
                    445:                tcp_timers(tp, TCPT_KEEP);
                    446:                break;
                    447: 
                    448:        case TCPS_CLOSE_WAIT:
                    449:                tp->t_state = TCPS_LAST_ACK;
                    450:                tp->so_options |= SO_KEEPALIVE;
                    451:                tcp_timers(tp, TCPT_KEEP);
                    452:                break;
                    453:        }
                    454:        if(tp && tp->t_state >= TCPS_FIN_WAIT_2) {
                    455:                tp->so_state &= ~(SS_PLEASEOPEN|SS_RCVATMARK);
                    456:                if(tp->so_state&SS_OPEN && !(tp->so_state&SS_HUNGUP)) {
                    457:                        tp->so_state |= SS_HUNGUP;
                    458:                        tcp_hungup(tp);
                    459:                }
                    460:        }
                    461:        return(tp);
                    462: }
                    463: 
                    464: tcp_isconnected(tp)
                    465: struct tcpcb *tp;
                    466: {
                    467:        struct block *bp;
                    468:        struct tcpuser *tu;
                    469:        struct tcpcb *rtp;
                    470: 
                    471:        if(tp->so_head)
                    472:                rtp = tp->so_head;
                    473:        else
                    474:                rtp = tp;
                    475:        if((rtp->so_state & SS_OPEN) == 0){
                    476:                printf("isconnected, no fd ref\n");
                    477:                return -1;
                    478:        }
                    479:        bp = allocb(sizeof(struct tcpuser));
                    480:        if(bp == 0)
                    481:                return -1;
                    482:        bp->wptr += sizeof(struct tcpuser);
                    483:        tu = (struct tcpuser *)bp->rptr;
                    484:        tu->code = TCPC_OK;
                    485:        tu->fport = tp->so_fport;
                    486:        tu->faddr = tp->so_faddr;
                    487:        tu->lport = tp->so_lport;
                    488:        tu->laddr = tp->so_laddr;
                    489:        tu->param = tp->so_dev;
                    490:        bp->class |= S_DELIM;
                    491:        return tcpdrint(bp, rtp);
                    492: }
                    493: 
                    494: tcp_hungup(tp)
                    495: register struct tcpcb *tp;
                    496: {
                    497:        register struct queue *q;
                    498: 
                    499:        q = tp->so_rq;
                    500:        if(q == 0)
                    501:                return;
                    502:        qpctl(q, M_HANGUP);
                    503: }
                    504: 
                    505: /*
                    506:  * find a spare even-numbered tcp device for a new passive-end
                    507:  * connection.
                    508:  */
                    509: struct tcpcb *
                    510: tcp_newconn(tp)
                    511: register struct tcpcb *tp;
                    512: {
                    513:        register struct tcpcb *ntp;
                    514:        register struct tcpcb *tend;
                    515: 
                    516:        if(tp->so_rq && (tp->so_rq->flag&QFULL)){
                    517:                printf("listen %d q full\n", tp->so_lport);
                    518:                return(0);
                    519:        }
                    520:        tend = &tcpcb[tcpcnt];
                    521:        for(ntp = &tcpcb[0]; ntp < tend; ntp += 2){
                    522:                if(ntp->t_state == TCPS_CLOSED){
                    523:                        bzero(ntp, sizeof(struct tcpcb));
                    524:                        ntp->t_maxseg = TCP_DEFMAXSEG;
                    525:                        ntp->so_options = tp->so_options & SO_KEEPALIVE;
                    526:                        ntp->so_head = tp;
                    527:                        ntp->so_dev = ntp - tcpcb;
                    528:                        return(ntp);
                    529:                }
                    530:        }
                    531:        return(0);
                    532: }
                    533: 
                    534: struct tcpcb *
                    535: tcpcb_lookup(faddr, fport, laddr, lport)
                    536: register in_addr faddr, laddr;
                    537: register tcp_port fport, lport;
                    538: {
                    539:        register struct tcpcb *tp;
                    540:        int highscore = 0, score;
                    541:        struct tcpcb *match = 0;
                    542:        struct tcpcb *tend;
                    543: 
                    544:        tend = &tcpcb[tcpcnt];
                    545:        for(tp = &tcpcb[0]; tp < tend; tp++){
                    546:                if(tp->t_state == TCPS_CLOSED)
                    547:                        continue;
                    548:                score = 22;
                    549:                if(tp->so_faddr != faddr) {
                    550:                        if(tp->so_faddr != INADDR_ANY)
                    551:                                continue;
                    552:                        else
                    553:                                score -=8;
                    554:                }
                    555:                if(tp->so_fport != fport) {
                    556:                        if(tp->so_fport != TCPPORT_ANY)
                    557:                                continue;
                    558:                        else
                    559:                                score -=8;
                    560:                }
                    561:                if(tp->so_laddr != laddr) {
                    562:                        if(tp->so_laddr == in_netof(laddr))
                    563:                                score -=1;
                    564:                        else if(tp->so_laddr != INADDR_ANY)
                    565:                                continue;
                    566:                        else
                    567:                                score -=2;
                    568:                }
                    569:                if(tp->so_lport != lport) {
                    570:                        if(tp->so_lport != TCPPORT_ANY)
                    571:                                continue;
                    572:                        else
                    573:                                score -=4;
                    574:                }
                    575:                if (score==22)
                    576:                        return tp;
                    577:                if (score<highscore)
                    578:                        continue;
                    579:                match = tp;
                    580:                highscore = score;
                    581:        }
                    582:        return(match);
                    583: }
                    584: 
                    585: /* n chars were acked; drop them now */
                    586: sbsnddrop(tp, n)
                    587: register struct tcpcb *tp;
                    588: register int n;
                    589: {
                    590:        register struct queue *q;
                    591:        register int i;
                    592:        register struct block *bp;
                    593: 
                    594:        q = tp->so_wq;
                    595:        if(q == 0)
                    596:                return;
                    597:        bp = 0;
                    598:        while(n > 0 && (bp = getq(q))){
                    599:                i = MIN(BLEN(bp), n);
                    600:                bp->rptr += i;
                    601:                n -= i;
                    602:                tp->so_wcount -= i;
                    603:                if(bp->rptr >= bp->wptr){
                    604:                        freeb(bp);
                    605:                        bp = 0;
                    606:                } else if(n > 0){
                    607:                        panic("sbsnddrop");
                    608:                }
                    609:        }
                    610:        if(bp)
                    611:                putbq(q, bp);
                    612: }
                    613: 
                    614: static tcp_port portnext[] = { 600, 1024 };
                    615: static tcp_port portlow[] = { 600, 1024 };
                    616: static tcp_port porthigh[] = { 1024, 2048 };
                    617: 
                    618: tcpcb_bind(tp, addr, port)
                    619: register struct tcpcb *tp;
                    620: register in_addr addr;
                    621: register tcp_port port;
                    622: {
                    623:        register int i;
                    624: 
                    625:        tp->so_lport = 0;
                    626:        if(port){
                    627:                /*
                    628:                 *  Don't let just anyone get a trusted port.
                    629:                 */
                    630:                if(port<porthigh[0] && u.u_uid!=0)
                    631:                        return(1);
                    632:                tp->so_lport = port;
                    633:                tp->so_laddr = addr;
                    634:                return(0);
                    635:        }
                    636:        /*
                    637:         *  No specific port, pick one.  Root only gets a trusted
                    638:         *  port if explicitly requested, so privileged programs
                    639:         *  can make non-privileged calls.
                    640:         */
                    641:        i = (u.u_uid==0 && (tp->so_options&SO_TRUSTED)) ? 0 : 1;
                    642:        if(portnext[i] >= porthigh[i])
                    643:                portnext[i] = portlow[i];
                    644:        port = portnext[i];
                    645:        while(1){
                    646:                if(tcpcb_bind(tp, addr, portnext[i]) == 0){
                    647:                        portnext[i]++;
                    648:                        return(0);
                    649:                }
                    650:                portnext[i]++;
                    651:                if(portnext[i] >= porthigh[i])
                    652:                        portnext[i] = portlow[i];
                    653:                if(portnext[i] == port) /* tried them all */
                    654:                        break;
                    655:        }
                    656:        return(1);
                    657: }
                    658: 
                    659: tcp_cantrcvmore(tp)
                    660: register struct tcpcb *tp;
                    661: {
                    662:        register struct queue *q;
                    663: 
                    664:        q = tp->so_rq;
                    665:        if(q == NULL)
                    666:                return;
                    667:        if(tp->so_state & SS_HANGUP)
                    668:                qpctl(q, M_HANGUP);
                    669:        else {
                    670:                /* two delims ensure a zero length read at the process */
                    671:                qpctld(q, M_DATA);
                    672:                qpctld(q, M_DATA);
                    673:        }
                    674: }

unix.superglobalmegacorp.com

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