Annotation of kernel/bsd/netat/adsp_Packet.c, revision 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.