Annotation of kernel/bsd/netat/adsp_Packet.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: 
                     26: #include <adsp_local.h>
                     27: #include <lap.h>
                     28: #include <at/at_lap.h>
                     29: #include <at/ddp.h>
                     30: extern at_ddp_cfg_t ddpcfg;
                     31: 
                     32: /*
                     33:  * GleanSession
                     34:  *
                     35:  * We just got a packet for this session, glean its address &
                     36:  * reset probe timer
                     37:  *
                     38:  * INPUTS:
                     39:  *    Session
                     40:  * OUTPUTS:
                     41:  *    none
                     42:  */
                     43: static void GleanSession(sp)           /* (CCBPtr sp) */
                     44:     CCBPtr sp;
                     45: {
                     46:     if (sp->openState == O_STATE_OPEN) {
                     47:        /* This is true for both state = sOpen & sClosing */
                     48:         RemoveTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer);
                     49:        InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer, 
                     50:                        sp->probeInterval);
                     51:        sp->probeCntr   = 4;
                     52:     }
                     53: 
                     54: }
                     55: 
                     56: 
                     57: /*
                     58:  * The same code handles incoming Open Connection Request,
                     59:  * Open Request + Ack, Open Connection Ack, Open Connection Denial
                     60:  *
                     61:  * We could be in four different states, LISTEN, OPENWAIT, ESTABLISHED,
                     62:  * OPEN.
                     63:  */
                     64: 
                     65: /*
                     66:  *
                     67:  * Ok, there are 16 combinations.  8 are do-nothings, 2 have to be
                     68:  * special cased (Open Deny and Req+Ack on Open session)
                     69:  *
                     70:  * Build a table of actions:
                     71:  *    Ignore?
                     72:  *    What to match on (local socket, whole address, DestCID, SrcCID)
                     73:  *    What to send (Ack or Req+Ack)
                     74:  *    Next State (both the ccb state and the open state)
                     75:  */
                     76: 
                     77: /*
                     78:  *
                     79:  */
                     80: typedef struct {
                     81:     u_char match;              /* Characteristics that have to match 
                     82:                                 * (Bit-Mapped, see below) */
                     83:     char action;               /* What to do if CCB matches */
                     84:     char send;                 /* What to send in response 
                     85:                                 * (Bit mapped, same as sendCtl field of 
                     86:                                 * CCB) */
                     87:     char openState;            /* Next Open state */
                     88:     char state;                        /* Next ccb state. */
                     89:     char pad;                  /* Too bad we need this to make structure 
                     90:                                 * even size */
                     91: } TBL, *TBLPtr;
                     92: 
                     93: #define M_LSOC         0x01    /* bit  0 - Match on local socket */
                     94: #define M_ADDR         0x02    /* bit  1 - Match on whole address */
                     95: #define M_DCID         0x04    /* bit  2 - Match on DestCID */
                     96: #define M_SCID         0x08    /* bit  3 - Match SrcCID */
                     97: #define M_DCIDZERO     0x10    /* bit  4 - Dest CID must be 0 */
                     98: #define M_SCIDZERO     0x20    /* bit  5 - Src CID must be 0 */
                     99: #define M_FILTER       0x40    /* bit  6 - Match address filter */
                    100: #define M_IGNORE       0x80    /* bit  7 - Ignore */
                    101: 
                    102: #define A_COMPLETE     0x01    /* Complete open parameter block */
                    103: #define A_SAVEPARMS    0x02    /* Save connection parameters */
                    104: #define A_OREQACKOPEN  0x04    /* special case for open Req+Ack on 
                    105:                                 * OPEN session */
                    106: #define A_GLEAN                0x08    /* We'll be talking back to this guy */
                    107: #define A_DENY         0x10    /* We've been denied! */
                    108: 
                    109: 
                    110: /*
                    111:  * So here's our table
                    112:  */
                    113: 
                    114: static TBL tbl[16] = {
                    115: 
                    116: /*
                    117:  * For Open Request ($81)
                    118:  *
                    119:  *     LISTENING
                    120:  *             Match on destination socket
                    121:  *             Match on address filter
                    122:  *             Dest CID must be 0
                    123:  *             Glean connection
                    124:  *             Save Open Connection parameters
                    125:  *             Send OREQACK
                    126:  *             Change state to ESTABLISHED
                    127:  */
                    128:        {       M_LSOC + M_DCIDZERO + M_FILTER,
                    129:                A_SAVEPARMS + A_GLEAN,
                    130:                B_CTL_OREQACK,
                    131:                O_STATE_ESTABLISHED,
                    132:                sOpening,
                    133:                0
                    134:        },
                    135: 
                    136: /*
                    137:  *
                    138:  *     OPENWAIT
                    139:  *             Match on Remote Address & destination socket
                    140:  *             Dest CID must be 0
                    141:  *             Save Open Connection parameters
                    142:  *             Send Ack
                    143:  *             Change state to ESTABLISHED
                    144:  */
                    145:        {       M_LSOC + M_ADDR + M_DCIDZERO,
                    146:                A_SAVEPARMS + A_GLEAN,
                    147:                B_CTL_OACK,
                    148:                O_STATE_ESTABLISHED,
                    149:                sOpening,
                    150:                0
                    151:        },
                    152: /*
                    153:  *
                    154:  *     ESTABLISHED
                    155:  *             Match on Remote Address & SrcCID
                    156:  *             Dest CID must be 0
                    157:  *             Send Req + Ack
                    158:  */
                    159:        {       M_ADDR + M_SCID + M_DCIDZERO, 
                    160:                A_GLEAN, 
                    161:                B_CTL_OACK, 
                    162:                O_STATE_ESTABLISHED,
                    163:                sOpening,
                    164:                0
                    165:        },
                    166: /*
                    167:  *     OPEN
                    168:  *             Ignore
                    169:  */
                    170:        {       M_IGNORE, 
                    171:                0, 
                    172:                0, 
                    173:                0,
                    174:                0,
                    175:                0
                    176:        },
                    177: 
                    178: /*
                    179:  *
                    180:  * For Open Ack ($82)
                    181:  *
                    182:  *     LISTENING
                    183:  *             Ignore
                    184:  */
                    185:        {       M_IGNORE, 
                    186:                0, 
                    187:                0, 
                    188:                0,
                    189:                0,
                    190:                0
                    191:        },
                    192: /*
                    193:  *
                    194:  *     OPENWAIT
                    195:  *             Ignore
                    196:  */
                    197:        {       M_IGNORE, 
                    198:                0, 
                    199:                0, 
                    200:                0, 
                    201:                0, 
                    202:                0
                    203:        },
                    204: /*
                    205:  *
                    206:  *     ESTABLISHED
                    207:  *             Match on SrcCID & DestCID & Address & Local Socket
                    208:  *             Complete Listen or Connect PB
                    209:  *             OPEN
                    210:  */
                    211:        {       M_ADDR + M_DCID + M_SCID + M_LSOC, 
                    212:                A_COMPLETE + A_GLEAN, 
                    213:                0, 
                    214:                O_STATE_OPEN,
                    215:                sOpen,
                    216:                0
                    217:        },
                    218: /*
                    219:  *
                    220:  *     OPEN
                    221:  *             Ignore
                    222: */
                    223:        {       M_IGNORE, 
                    224:                0, 
                    225:                0, 
                    226:                0, 
                    227:                0, 
                    228:                0
                    229:        },
                    230: 
                    231: /*
                    232:  *
                    233:  * For Open Request + Ack ($83)
                    234:  *
                    235:  *     LISTENING
                    236:  *             Ignore
                    237: */
                    238:        {       M_IGNORE, 
                    239:                0, 
                    240:                0, 
                    241:                0, 
                    242:                0, 
                    243:                0
                    244:        },
                    245: /*
                    246:  *
                    247:  *     OPENWAIT
                    248:  *             Match on DestCID & socket
                    249:  *                     Do not test remote address -- our open req could have
                    250:  *                     been passed to another address by a connection server
                    251:  *             Save Open Connection parameters
                    252:  *             Complete Connect parameter block
                    253:  *             Send Ack
                    254:  *             OPEN
                    255:  */
                    256:        {       M_DCID + M_LSOC,
                    257:                A_COMPLETE + A_SAVEPARMS + A_GLEAN,
                    258:                B_CTL_OACK,
                    259:                O_STATE_OPEN,
                    260:                sOpen,
                    261:                0
                    262:        },
                    263: /*
                    264:  *
                    265:  *     ESTABLISHED
                    266:  *             Ignore
                    267:  */
                    268:        {       M_IGNORE, 
                    269:                0, 
                    270:                0, 
                    271:                0, 
                    272:                0, 
                    273:                0
                    274:        },
                    275: /*
                    276:  *
                    277:  *     OPEN
                    278:  *             Match on Remote Address & SrcCID & DestCID & Local Socket
                    279:  *             If we've never gotten any data
                    280:  *             Send Ack & Retransmit
                    281:  */
                    282:        {       M_ADDR + M_DCID + M_SCID + M_LSOC,
                    283:                A_OREQACKOPEN + A_GLEAN,
                    284:                B_CTL_OACK,
                    285:                O_STATE_OPEN,
                    286:                sOpen,
                    287:                0
                    288:        },
                    289: 
                    290: /*
                    291:  *
                    292:  *
                    293:  * For Open Deny ($84)
                    294:  *
                    295:  *     LISTENING
                    296:  *             Ignore
                    297:  */
                    298:        {       M_IGNORE, 
                    299:                0, 
                    300:                0, 
                    301:                0, 
                    302:                0, 
                    303:                0
                    304:        },
                    305: /*
                    306:  *
                    307:  *     OPENWAIT
                    308:  *             Match on DestCID & Address
                    309:  *             Source CID must be 0
                    310:  *             Complete with error
                    311:  */
                    312:        {       M_SCIDZERO + M_DCID + M_ADDR, 
                    313:                A_DENY,
                    314:                0, 
                    315:                O_STATE_NOTHING,
                    316:                sClosed,
                    317:                0
                    318:        },
                    319: /*
                    320:  *
                    321:  *     ESTABLISHED
                    322:  *             Ignore
                    323:  */
                    324:        {       M_IGNORE, 
                    325:                0, 
                    326:                0, 
                    327:                0, 
                    328:                0, 
                    329:                0
                    330:        },      /* %%% No we probably don't want to ignore in this case */
                    331: /*
                    332:  *
                    333:  *    OPEN
                    334:  *       Ignore
                    335:  */
                    336:        {       M_IGNORE, 
                    337:                0, 
                    338:                0, 
                    339:                0, 
                    340:                0, 
                    341:                0
                    342:        }
                    343: };
                    344: 
                    345: /*
                    346:  * Used to search down queue of sessions for a session waiting for an
                    347:  * open request.
                    348:  */
                    349: typedef struct {
                    350:    AddrUnion   addr;
                    351:    word                dstCID;
                    352:    word                srcCID;
                    353:    byte                socket;
                    354:    byte                descriptor;
                    355:    byte                idx;            /* Index into state tables */
                    356:    TBLPtr      t;              /* Ptr to entry in table above */
                    357: } MATCH, *MATCHPtr;
                    358: 
                    359: /*
                    360:  * MatchStream
                    361:  *
                    362:  * Called by Rx connection to find which stream (if any) should get this open
                    363:  * request/ack/req+ack/deny packet.
                    364:  *
                    365:  */
                    366: 
                    367: static boolean
                    368: MatchStream(sp, m)             /* (CCBPtr sp, MATCHPtr m) */
                    369:     CCBPtr sp;
                    370:     MATCHPtr m;
                    371: {
                    372:        unsigned char match;
                    373:        struct adspcmd  *opb;
                    374:     
                    375:        if (sp->openState < O_STATE_LISTEN ||
                    376:            sp->openState > O_STATE_OPEN)
                    377:            return 0;
                    378: 
                    379: 
                    380:        m->t = &tbl[sp->openState - O_STATE_LISTEN + m->idx];
                    381: 
                    382:        match = m->t->match;    /* Get match criteria */
                    383: 
                    384:        if (match & M_IGNORE)   /* Ignore this combination */
                    385:            return 0;
                    386: 
                    387:        if (match & M_LSOC) {   /* Match on Local socket */
                    388:            if (sp->localSocket != m->socket)
                    389:                return 0;
                    390:        }
                    391: 
                    392:        if (match & M_ADDR) {   /* Match on Address */
                    393:            AddrUnion   addr;
                    394:            addr = m->addr;     /* Make local copy for efficiency */
                    395:            if (sp->remoteAddress.a.node != addr.a.node)
                    396:                return 0;
                    397:            if (sp->remoteAddress.a.socket != addr.a.socket)
                    398:                return 0;
                    399:            if ((NET_VALUE(sp->remoteAddress.a.net) && NET_VALUE(addr.a.net)) &&
                    400:                (NET_VALUE(sp->remoteAddress.a.net) != NET_VALUE(addr.a.net)))
                    401:                return 0;
                    402:                        
                    403:            /*
                    404:             * Handle special case to reject self-sent open request
                    405:             */
                    406:            if ((m->srcCID == sp->locCID) && 
                    407:                (addr.a.node == ddpcfg.node_addr.node) && 
                    408:                ((NET_VALUE(addr.a.net) == 0) || 
                    409:                 (NET_VALUE(ddpcfg.node_addr.net) == 0) || 
                    410:                 (NET_VALUE(ddpcfg.node_addr.net) == NET_VALUE(addr.a.net))) )
                    411:                                /* CID's match, and */
                    412:                                /* If nodeID matches, and */
                    413:                                /* network matches, */
                    414:                return 0;       /* then came from us! */
                    415:        }
                    416:        
                    417:        if (match & M_DCID) {   /* Match on DestCID */
                    418:            if (sp->locCID != m->dstCID)
                    419:                return 0;
                    420:        }
                    421:        
                    422:        if (match & M_SCID) {   /* Match on SourceCID */
                    423:            if (sp->remCID != m->srcCID)
                    424:                return 0;
                    425:        }
                    426:        
                    427:        if (match & M_DCIDZERO) { /* Destination CID must be 0 */
                    428:            if (m->dstCID != 0)
                    429:                return 0;
                    430:        }
                    431:        
                    432:        if (match & M_SCIDZERO) /* Source CID must be 0 */
                    433:        {
                    434:            if (m->srcCID != 0)
                    435:                return 0;
                    436:        }
                    437:        
                    438:        if (match & M_FILTER) { /* Check address filter? */
                    439:            if (opb = sp->opb)  /* There should be a param block... */
                    440:            {
                    441:                AddrUnion       addr;
                    442:                addr = m->addr; /* Make local copy for efficiency */
                    443:                if ((NET_VALUE(opb->u.openParams.filterAddress.net) && 
                    444:                     NET_VALUE(addr.a.net) &&
                    445:                     NET_VALUE(opb->u.openParams.filterAddress.net) != NET_VALUE(addr.a.net)) ||
                    446:                    (opb->u.openParams.filterAddress.node != 0 &&
                    447:                     opb->u.openParams.filterAddress.node != addr.a.node)||
                    448:                    (opb->u.openParams.filterAddress.socket != 0 &&
                    449:                     opb->u.openParams.filterAddress.socket != addr.a.socket))
                    450:                    return 0;
                    451:            }
                    452:        }
                    453:        
                    454:        return 1;
                    455: }
                    456: 
                    457: /*
                    458:  * MatchListener
                    459:  *
                    460:  * Called by rx connection to see which connection listener (if any) should
                    461:  * get this incoming open connection request.
                    462:  *
                    463:  */
                    464: 
                    465: static boolean MatchListener(sp, m) /* (CCBPtr sp, MATCHPtr m) */
                    466:     CCBPtr sp;
                    467:     MATCHPtr m;
                    468: {
                    469: 
                    470:     if ((sp->state == (word)sListening) && /* This CCB is a listener */
                    471:        (sp->localSocket == m->socket)) /* on the right socket */
                    472:        return 1;
                    473:     
                    474:     return 0;
                    475: }
                    476: 
                    477: /*
                    478:  * RXConnection
                    479:  *
                    480:  * We just received one of the 4 Open Connection packets
                    481:  * Interrupts are masked OFF at this point
                    482:  *
                    483:  * INPUTS:
                    484:  *     spPtr   Place to put ptr to stream (if we found one -- not 
                    485:  *                                             for listeners)
                    486:  *     f       Pointer to ADSP header for packet, data follows behind it
                    487:  *     len     # of byte in ADSP header + data
                    488:  *     addr    Who sent the packet
                    489:  *     dsoc    Where they sent it to
                    490:  *
                    491:  * OUTPUTS:
                    492:  *    Returns 1 if packet was ignored
                    493:  */
                    494: static int RXConnection(gref, spPtr, f, len, addr, dsoc) 
                    495:     /* (CCBPtr *spPtr, ADSP_FRAMEPtr f, word len, AddrUnion addr, byte dsoc) */
                    496:     gref_t *gref;                      /* READ queue */
                    497:     CCBPtr *spPtr;
                    498:     ADSP_FRAMEPtr f;
                    499:     int len;
                    500:     AddrUnion addr;
                    501:     unsigned char dsoc;
                    502: {
                    503:     CCBPtr sp;
                    504:     ADSP_OPEN_DATAPtr op;
                    505:     struct adspcmd *pb;
                    506:     MATCH m;
                    507:     gbuf_t *mp;
                    508:     ADSP_FRAMEPtr adspp;
                    509:     ADSP_OPEN_DATAPtr adspop;
                    510:     int s;
                    511: 
                    512:     op = (ADSP_OPEN_DATAPtr)&f->data[0]; /* Point to Open-Connection parms */
                    513:     len -= ADSP_FRAME_LEN;
                    514:     
                    515:     if (len < (sizeof(ADSP_OPEN_DATA))) /* Packet too small */
                    516:        return 1;
                    517: 
                    518: 
                    519:     if (UAS_VALUE(op->version) != netw(0x0100)) { /* Check version num (on even-byte) */
                    520:        /*
                    521:         * The open request has been denied.  Try to send him a denial.  
                    522:         */
                    523: 
                    524:        mp = gbuf_alloc(AT_WR_OFFSET + DDPL_FRAME_LEN + ADSP_FRAME_LEN + ADSP_OPEN_FRAME_LEN,
                    525:                    PRI_LO);
                    526:        gbuf_rinc(mp,AT_WR_OFFSET);
                    527:        gbuf_wset(mp,DDPL_FRAME_LEN);
                    528:        adspp = (ADSP_FRAMEPtr)gbuf_wptr(mp);
                    529:        gbuf_winc(mp,ADSP_FRAME_LEN);
                    530:        bzero((caddr_t) gbuf_rptr(mp),DDPL_FRAME_LEN + ADSP_FRAME_LEN + 
                    531:              ADSP_OPEN_FRAME_LEN);
                    532:        adspp->descriptor = ADSP_CONTROL_BIT | ADSP_CTL_ODENY;
                    533:        adspop = (ADSP_OPEN_DATAPtr)gbuf_wptr(mp);
                    534:        gbuf_winc(mp,ADSP_OPEN_FRAME_LEN);
                    535:        UAS_UAS(adspop->dstCID, f->CID);
                    536:        UAS_ASSIGN(adspop->version, 0x100);
                    537:        adsp_sendddp(0, mp, DDPL_FRAME_LEN + ADSP_FRAME_LEN + 
                    538:                   ADSP_OPEN_FRAME_LEN, &addr, DDP_ADSP);
                    539: 
                    540:        return 0;
                    541:     }
                    542:     m.addr = addr;
                    543:     m.socket = dsoc;
                    544:     m.descriptor = f->descriptor;
                    545:     m.srcCID = UAS_VALUE(f->CID);
                    546:     m.dstCID = UAS_VALUE(op->dstCID);  /* On even-byte boundry */
                    547:     m.idx = ((f->descriptor & ADSP_CONTROL_MASK) - 1) * 4;
                    548:                                           
                    549:     /*
                    550:      * See if we can find a stream that knows what to do with this packet
                    551:      */
                    552:     if ((sp = (CCBPtr)qfind_m(AT_ADSP_STREAMS, &m, (ProcPtr)MatchStream)) == 0)
                    553:     {
                    554:        struct adspcmd *p;
                    555:        struct adspcmd *n;
                    556:        struct adspcmd *ot_n;
                    557:        gbuf_t *ot_mp;
                    558:        /*
                    559:         * No match, so look for connection listeners if this is an 
                    560:         * open request
                    561:         */
                    562:        if ((f->descriptor & ADSP_CONTROL_MASK) != (byte)ADSP_CTL_OREQ)
                    563:            return 1;
                    564: 
                    565:        if ((sp = (CCBPtr)qfind_m(AT_ADSP_STREAMS, &m, 
                    566:                                  (ProcPtr)MatchListener)) == 0)
                    567:            return 1;
                    568: 
                    569:        ATDISABLE(s, sp->lock);
                    570:        p = (struct adspcmd *)&sp->opb;
                    571:        while (n = (struct adspcmd *)p->qLink) /* Hunt down list of listens */
                    572:        {
                    573:            /* Check address filter */
                    574:            if (((NET_VALUE(n->u.openParams.filterAddress.net) == 0) ||
                    575:                 (NET_VALUE(addr.a.net) == 0) ||
                    576:                 (NET_VALUE(n->u.openParams.filterAddress.net) == NET_VALUE(addr.a.net))) &&
                    577:                
                    578:                ((n->u.openParams.filterAddress.node == 0) || 
                    579:                 (n->u.openParams.filterAddress.node == addr.a.node)) &&
                    580:                
                    581:                ((n->u.openParams.filterAddress.socket == 0) || 
                    582:                 (n->u.openParams.filterAddress.socket == addr.a.socket))) {
                    583:                p->qLink = n->qLink; /* Unlink this param block */
                    584:                n->u.openParams.remoteCID = m.srcCID;
                    585:                *((AddrUnionPtr)&n->u.openParams.remoteAddress) = addr;
                    586:                n->u.openParams.sendSeq = netdw(UAL_VALUE(f->pktNextRecvSeq));
                    587:                n->u.openParams.sendWindow = netw(UAS_VALUE(f->pktRecvWdw));
                    588:                n->u.openParams.attnSendSeq = netdw(UAL_VALUE(op->pktAttnRecvSeq));
                    589:                n->ioResult = 0;
                    590:                ATENABLE(s, sp->lock);
                    591:                completepb(sp, n); /* complete copy of request */
                    592:                                /* complete(n, 0); */
                    593:                return 0;
                    594:            }                   /* found CLListen */
                    595:                        
                    596:            p = n;              /* down the list we go... */
                    597:                        
                    598:        }                       /* while */
                    599:                
                    600:        ATENABLE(s, sp->lock);
                    601:        return 1;
                    602:     }
                    603:        
                    604:     *spPtr = sp;               /* Save ptr to stream we just found */
                    605:        
                    606:        ATDISABLE(s, sp->lock);
                    607:     sp->openState = m.t->openState; /* Move to next state (may be same) */
                    608:     sp->state = m.t->state;    /* Move to next state (may be same) */
                    609: 
                    610:     if (m.t->action & A_SAVEPARMS) { /* Need to Save open-conn parms */
                    611:        sp->firstRtmtSeq = sp->sendSeq = netdw(UAL_VALUE(f->pktNextRecvSeq));
                    612:        sp->sendWdwSeq = netdw(UAL_VALUE(f->pktNextRecvSeq)) + netw(UAS_VALUE(f->pktRecvWdw)) - 1;
                    613:        sp->attnSendSeq = netdw(UAL_VALUE(op->pktAttnRecvSeq)); /* on even boundry */
                    614: 
                    615:                
                    616:        sp->remCID = UAS_VALUE(f->CID); /* Save Source CID as RemCID */
                    617:        UAS_UAS(sp->of.dstCID, f->CID); /* Save CID in open ctl packet */
                    618:                
                    619:        sp->remoteAddress = addr; /* Save his address */
                    620: 
                    621:     }
                    622:        ATENABLE(s, sp->lock);
                    623: 
                    624:     if (m.t->action & A_DENY) {        /* We've been denied ! */
                    625:        DoClose(sp, errOpenDenied, -1);
                    626:     }
                    627: 
                    628:     if (m.t->action & A_OREQACKOPEN) { 
                    629:                                /* Special case for OREQACK */
                    630:                                /* on an open session */
                    631:         RemoveTimerElem(&adspGlobal.fastTimers, &sp->RetryTimer);
                    632:        sp->sendSeq = sp->firstRtmtSeq;
                    633:        sp->pktSendCnt  = 0;
                    634:        sp->waitingAck  = 0;
                    635:        sp->callSend = 1;
                    636:     }
                    637: 
                    638:     if (m.t->send) {           /* Need to send a response */
                    639:        sp->sendCtl |= m.t->send;
                    640:        sp->callSend = 1;
                    641:     }
                    642: 
                    643:     if (m.t->action & A_COMPLETE) { /* Need to complete open param blk */
                    644:         RemoveTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer);
                    645:                        
                    646:        if (pb = sp->opb) {
                    647:            sp->opb = 0;
                    648:            pb->u.openParams.localCID = sp->locCID;
                    649:            pb->u.openParams.remoteCID = sp->remCID;
                    650:            pb->u.openParams.remoteAddress = 
                    651:                *((at_inet_t *)&sp->remoteAddress);
                    652:            pb->u.openParams.sendSeq = sp->sendSeq;
                    653:            pb->u.openParams.sendWindow = sp->sendWdwSeq - sp->sendSeq;
                    654:            pb->u.openParams.attnSendSeq = sp->attnSendSeq;
                    655:            pb->ioResult = 0;
                    656:            completepb(sp, pb); /* complete(pb, 0); */
                    657:            return 0;
                    658:        }
                    659:                                /* Start probe timer */
                    660:        InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer, 
                    661:                        sp->probeInterval);
                    662:     }
                    663:     return 0;
                    664: }
                    665: 
                    666: /*
                    667:  * ADSPPacket
                    668:  *
                    669:  * When a packet is received by the protocol stack with DDP type equal
                    670:  * to ADSP, then execution comes here
                    671:  *
                    672:  * DS is set to ATALK's DGROUP
                    673:  *
                    674:  * This routine, or one of its children MUST call glean packet
                    675:  *
                    676:  * INPUTS:
                    677:  *    Pointer to DDP header 
                    678:  * OUTPUTS:
                    679:  *    none
                    680:  *
                    681:  * Note that the incoming message block (mp) is usually discarded, either
                    682:  * by the "ignored" path, or via the "checksend" path.  The only case
                    683:  * where the message is NOT freed is via the RxData case in the
                    684:  * non control packet switch.  I zero mp after the RxData case succeeds
                    685:  * so that mp will not be freed.
                    686:  */
                    687: int adspPacket(gref, mp) 
                    688:     /* (bytePtr data, word len, AddrUnion a, byte dsoc) */
                    689:     gref_t *gref;
                    690:     gbuf_t *mp;
                    691: {
                    692:     unsigned char *bp;
                    693:     int len;
                    694:     AddrUnion a;
                    695:     int dsoc;
                    696:     int s;
                    697:     register DDPX_FRAME *ddp;  /* DDP frame pointer */
                    698:     register ADSP_FRAMEPtr f;  /* Frame */
                    699:     CCBPtr sp;
                    700: 
                    701:     sp = 0;                    /* No stream */
                    702:     bp = (unsigned char *)gbuf_rptr(mp);
                    703:     ddp = (DDPX_FRAME *)bp;
                    704:     if (ddp->ddpx_type != DDP_ADSP)
                    705:        return -1;
                    706:     f = (ADSP_FRAMEPtr)(bp + DDPL_FRAME_LEN);
                    707: 
                    708:     len = UAS_VALUE(ddp->ddpx_length) & 0x3ff; /* (ten bits of length) */
                    709:     len -= DDPL_FRAME_LEN;
                    710:     if (len < (sizeof(ADSP_FRAME) - 1))        /* Packet too small */
                    711:        return -1;              /* mark the failure */
                    712: 
                    713:     NET_NET(a.a.net, ddp->ddpx_snet);
                    714:     a.a.node = ddp->ddpx_snode;
                    715:     a.a.socket = ddp->ddpx_source;
                    716: 
                    717:     dsoc = ddp->ddpx_dest;
                    718: 
                    719:     if (sp = (CCBPtr)FindSender(f, a))
                    720:        GleanSession(sp);
                    721: 
                    722:     if (f->descriptor & ADSP_ATTENTION_BIT) { /* ATTN packet */
                    723:        if (sp && RXAttention(sp, mp, f, len)) 
                    724:            goto ignore;
                    725:        else
                    726:            mp = 0;             /* attention data is being held */
                    727:     }                          /* ATTENTION BIT */
                    728: 
                    729:     else if (f->descriptor & ADSP_CONTROL_BIT) { /* Control packet */
                    730:        switch (f->descriptor & ADSP_CONTROL_MASK) {
                    731:        case ADSP_CTL_PROBE:    /* Probe or acknowledgement */
                    732:            if (sp)
                    733:                CheckRecvSeq(sp, f);
                    734:            break;
                    735: 
                    736:        case ADSP_CTL_OREQ:     /* Open Connection Request */
                    737:        case ADSP_CTL_OREQACK:  /* Open Request and acknowledgement */
                    738:        case ADSP_CTL_OACK:     /* Open Request acknowledgment */
                    739:        case ADSP_CTL_ODENY:    /* Open Request denial */
                    740:            if (RXConnection(gref, &sp, f, len, a, dsoc))
                    741:                goto ignore;
                    742:            break;
                    743:                        
                    744:        case ADSP_CTL_CLOSE:    /* Close connection advice */
                    745:            if (sp) {
                    746:                /* This pkt may also ack some data we sent */
                    747:                CheckRecvSeq(sp, f); 
                    748:                RxClose(sp);
                    749:                sp = 0;
                    750:            } else
                    751:                goto ignore;
                    752:            break;
                    753: 
                    754:        case ADSP_CTL_FRESET:   /* Forward Reset */
                    755:                                /* May I rot in hell for the code below... */
                    756:            if (sp && (CheckRecvSeq(sp, f), RXFReset(sp, f)))
                    757:                goto ignore;
                    758:            break;
                    759:                        
                    760:        case ADSP_CTL_FRESET_ACK: /* Forward Reset Acknowledgement */
                    761:            if (sp && (CheckRecvSeq(sp, f), RXFResetAck(sp, f)))
                    762:                goto ignore;
                    763:            break;
                    764: 
                    765:        case ADSP_CTL_RETRANSMIT: /* Retransmit advice */
                    766:            if (sp) {
                    767:                /* This pkt may also ack some data we sent */
                    768:                CheckRecvSeq(sp, f); 
                    769:                RemoveTimerElem(&adspGlobal.fastTimers, &sp->RetryTimer);
                    770:                ATDISABLE(s, sp->lock);
                    771:                sp->sendSeq = sp->firstRtmtSeq;
                    772:                sp->pktSendCnt = 0;
                    773:                sp->waitingAck = 0;
                    774:                sp->callSend = 1;
                    775:                ATENABLE(s, sp->lock);
                    776:            } else
                    777:                goto ignore;
                    778:            break;
                    779:                        
                    780:        default:
                    781:            goto ignore;
                    782:        }                       /* switch */
                    783:     }                          /* Control packet */
                    784: 
                    785:     else {                     /* Data Packet */
                    786:        if ((sp == 0) || RXData(sp, mp, f, len))
                    787:            goto ignore;
                    788:        else
                    789:            mp = 0;             /* RXData used up the data, DONT free it! */
                    790:     }                          /* Data Packet */
                    791: 
                    792:     if (mp)
                    793:        gbuf_freem(mp);
                    794: 
                    795: checksend:                     /* incoming data was not ignored */
                    796:     if (sp && sp->callSend)    /* If we have a stream & we need to send */
                    797:        CheckSend(sp);
                    798:     
                    799:     return 0;
                    800:        
                    801: ignore:
                    802:     gbuf_freem(mp);
                    803:     return 0;
                    804: }

unix.superglobalmegacorp.com

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