Annotation of Gnu-Mach/chips/nc.c, revision 1.1.1.1

1.1       root        1: /* 
                      2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
                      4:  * All Rights Reserved.
                      5:  * 
                      6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
                     11:  * 
                     12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     15:  * 
                     16:  * Carnegie Mellon requests users of this software to return to
                     17:  * 
                     18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
                     22:  * 
                     23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
                     26: 
                     27: /*** NETWORK INTERFACE IMPLEMENTATION CORE ***/
                     28: 
                     29: #ifndef STUB
                     30: #include <chips/nc.h>
                     31: #else
                     32: #include "nc.h"
                     33: #endif
                     34: 
                     35: /*** Types and data structures ***/
                     36: 
                     37: #if PRODUCTION
                     38: #define MAX_HASH 701
                     39: #define MAX_HOST 4000
                     40: #else
                     41: #define MAX_HASH 7
                     42: #define MAX_HOST 4
                     43: #endif
                     44: 
                     45: nw_dev_entry_s nc_failure_entry_table =  {nc_fail, nc_fail,
                     46:                           nc_null, nc_null,
                     47:                           nc_null_poll, nc_null_send, nc_null_rpc,
                     48:                           nc_null_signal, nc_open_fail, nc_accept_fail,
                     49:                           nc_close_fail, nc_open_fail, nc_open_fail};
                     50:                                            
                     51: nw_dev_entry_s nc_local_entry_table =  {nc_succeed, nc_succeed,
                     52:                           nc_null, nc_null,
                     53:                           nc_null_poll, nc_local_send, nc_local_rpc,
                     54:                           nc_null_signal, nc_open_fail, nc_accept_fail,
                     55:                           nc_close_fail, nc_open_fail, nc_open_fail};
                     56: 
                     57: 
                     58: typedef struct {
                     59:   nw_address_s address;
                     60:   int name_next:16;
                     61:   int ip_next:16;
                     62:   int nw_next:16;
                     63:   nw_ep line:16;
                     64: } nw_alist_s, *nw_alist_t;
                     65:               
                     66: 
                     67: boolean_t nc_initialized = FALSE;
                     68: nw_tx_header_s nw_tx[MAX_EP/2];
                     69: nw_tx_header_t nw_free_tx_header;
                     70: nw_rx_header_s nw_rx[2*MAX_EP];
                     71: nw_rx_header_t nw_free_rx_header;
                     72: nw_plist_s nw_peer[MAX_EP];
                     73: nw_plist_t nw_free_peer;
                     74: 
                     75: nw_devcb devct[MAX_DEV];
                     76: 
                     77: nw_ecb ect[MAX_EP];
                     78: 
                     79: int nw_free_ep_first, nw_free_ep_last;
                     80: int nw_free_line_first, nw_free_line_last;
                     81: 
                     82: nw_alist_s nw_address[MAX_HOST];
                     83: int nw_free_address;
                     84: 
                     85: int nw_name[MAX_HASH];
                     86: int nw_ip[MAX_HASH];
                     87: int nw_nw[MAX_HASH];
                     88: 
                     89: int nw_fast_req;
                     90: 
                     91: /*** System-independent functions ***/
                     92: 
                     93: void nc_initialize() {
                     94:   int ep, last_ep;
                     95:   
                     96:   if (!nc_initialized) {
                     97:     last_ep = sizeof(nw_tx)/sizeof(nw_tx_header_s) - 1;
                     98:     for (ep = 0; ep < last_ep; ep++)
                     99:       nw_tx[ep].next = &nw_tx[ep+1];
                    100:     nw_tx[last_ep].next = NULL;
                    101:     nw_free_tx_header = &nw_tx[0];
                    102:     last_ep = sizeof(nw_rx)/sizeof(nw_rx_header_s) - 1;
                    103:     for (ep = 0; ep < last_ep; ep++)
                    104:       nw_rx[ep].next = &nw_rx[ep+1];
                    105:     nw_rx[last_ep].next = NULL;
                    106:     nw_free_rx_header = &nw_rx[0];
                    107:     last_ep = sizeof(nw_peer)/sizeof(nw_plist_s) - 1;
                    108:     for (ep = 0; ep < last_ep; ep++)
                    109:       nw_peer[ep].next = &nw_peer[ep+1];
                    110:     nw_peer[last_ep].next = NULL;
                    111:     nw_free_peer = &nw_peer[0];
                    112:     for (ep = 0; ep < MAX_DEV; ep++) {
                    113:       devct[ep].status = NW_FAILURE;
                    114:       devct[ep].type = NW_CONNECTIONLESS;
                    115:       devct[ep].addr = NULL;
                    116:       devct[ep].local_addr_1 = 0;
                    117:       devct[ep].local_addr_2 = 0;
                    118:       devct[ep].entry = &nc_failure_entry_table;
                    119:       devct[ep].fast_req = 0;
                    120:     }
                    121:     devct[NW_NULL].status = NW_SUCCESS;
                    122:     devct[NW_NULL].entry = &nc_local_entry_table;
                    123:     last_ep = sizeof(ect)/sizeof(nw_ecb);
                    124:     for (ep = 0; ep < last_ep; ep++) {
                    125:       ect[ep].state = NW_INEXISTENT;
                    126:       ect[ep].id = ep;
                    127:       ect[ep].seqno = 0;
                    128:       ect[ep].previous = ep - 1;
                    129:       ect[ep].next = ep + 1;
                    130:     }
                    131:     ect[0].next = ect[0].previous = 0;
                    132:     ect[last_ep-1].next = 0;
                    133:     nw_free_ep_first = 1;
                    134:     nw_free_ep_last = last_ep - 1;
                    135:     nw_free_line_first = nw_free_line_last = 0;
                    136:     for (ep = 0; ep < MAX_HOST; ep++) {
                    137:       nw_address[ep].nw_next = ep + 1;
                    138:     }
                    139:     nw_address[MAX_HOST - 1].nw_next = -1;
                    140:     nw_free_address = 0;
                    141:     for (ep = 0; ep < MAX_HASH; ep++) {
                    142:       nw_name[ep] = -1;
                    143:       nw_ip[ep] = -1;
                    144:       nw_nw[ep] = -1;
                    145:     }
                    146:     nw_fast_req = 0;
                    147:     h_initialize();
                    148:     nc_initialized = TRUE;
                    149:   }
                    150: }
                    151: 
                    152: nw_tx_header_t nc_tx_header_allocate() {
                    153:   nw_tx_header_t header;
                    154: 
                    155:   header = nw_free_tx_header;
                    156:   if (header != NULL)
                    157:     nw_free_tx_header = header->next;
                    158:   return header;
                    159: }
                    160: 
                    161: void nc_tx_header_deallocate(nw_tx_header_t header) {
                    162:   nw_tx_header_t first_header;
                    163: 
                    164:   first_header = header;
                    165:   while (header->next != NULL)
                    166:     header = header->next;
                    167:   header->next = nw_free_tx_header;
                    168:   nw_free_tx_header = first_header;
                    169: }
                    170: 
                    171: nw_rx_header_t nc_rx_header_allocate() {
                    172:   nw_rx_header_t header;
                    173: 
                    174:   header = nw_free_rx_header;
                    175:   if (header != NULL)
                    176:     nw_free_rx_header = header->next;
                    177:   return header;
                    178: }
                    179: 
                    180: void nc_rx_header_deallocate(nw_rx_header_t header) {
                    181: 
                    182:   header->next = nw_free_rx_header;
                    183:   nw_free_rx_header = header;
                    184: }
                    185: 
                    186: nw_plist_t nc_peer_allocate() {
                    187:   nw_plist_t peer;
                    188: 
                    189:   peer = nw_free_peer;
                    190:   if (peer != NULL)
                    191:     nw_free_peer = peer->next;
                    192:   return peer;
                    193: }
                    194: 
                    195: void nc_peer_deallocate(nw_plist_t peer) {
                    196:   nw_plist_t first_peer;
                    197: 
                    198:   first_peer = peer;
                    199:   while (peer->next != NULL)
                    200:     peer = peer->next;
                    201:   peer->next = nw_free_peer;
                    202:   nw_free_peer = first_peer;
                    203: }
                    204: 
                    205: 
                    206: nw_result nc_device_register(u_int dev, nw_dev_type type, char *dev_addr,
                    207:                             nw_dev_entry_t dev_entry_table) {
                    208:   nw_result rc;
                    209: 
                    210:   if (dev >= MAX_DEV) {
                    211:     rc = NW_FAILURE;
                    212:   } else {
                    213:     devct[dev].status = NW_SUCCESS;
                    214:     devct[dev].type = type;
                    215:     devct[dev].addr = dev_addr;
                    216:     devct[dev].entry = dev_entry_table;
                    217:     devct[dev].fast_req = 0;
                    218:     rc = NW_SUCCESS;
                    219:   }
                    220:   return rc;
                    221: }
                    222:   
                    223: nw_result nc_device_unregister(u_int dev, nw_result status) {
                    224:   nw_result rc;
                    225: 
                    226:   if (dev >= MAX_DEV) {
                    227:     rc = NW_FAILURE;
                    228:   } else {
                    229:     devct[dev].status = status;
                    230:     devct[dev].addr = NULL;
                    231:     devct[dev].entry = &nc_failure_entry_table;
                    232:     devct[dev].fast_req = 0;
                    233:     rc = NW_SUCCESS;
                    234:   }
                    235:   return rc;
                    236: }
                    237:   
                    238: void nc_slow_sweep() {
                    239:   int dev;
                    240: 
                    241:   for (dev = 0; dev < MAX_DEV; dev++) {
                    242:     if (devct[dev].status == NW_SUCCESS) {
                    243:       (*(devct[dev].entry->slow_sweep)) (dev);
                    244:     }
                    245:   }
                    246: }
                    247: 
                    248: void nc_fast_timer_set(int dev) {
                    249: 
                    250:   devct[dev].fast_req++;
                    251:   if (nw_fast_req++ == 0)
                    252:     h_fast_timer_set();
                    253: }
                    254: 
                    255: void nc_fast_timer_reset(int dev) {
                    256: 
                    257:   devct[dev].fast_req--;
                    258:   if (nw_fast_req-- == 0)
                    259:     h_fast_timer_reset();
                    260: }
                    261: 
                    262: 
                    263: void nc_fast_sweep() {
                    264:   int dev;
                    265: 
                    266:   for (dev = 0; dev < MAX_DEV; dev++) {
                    267:     if (devct[dev].status == NW_SUCCESS &&
                    268:        devct[dev].fast_req > 0) {
                    269:       devct[dev].fast_req = 0;
                    270:       (*(devct[dev].entry->fast_sweep)) (dev);
                    271:     }
                    272:   }
                    273: }
                    274: 
                    275: int nc_hash_name(char *cp) {
                    276:   int h;
                    277:   char ch;
                    278:   char *cp_end;
                    279: 
                    280:   cp_end = cp + 19;
                    281:   *cp_end = '\0';
                    282:   h = 0;
                    283:   ch = *cp++;
                    284:   while (ch != '\0') {
                    285:     h = (h << 7) + ch;
                    286:     ch = *cp++;
                    287:     if (ch != '\0') {
                    288:       h = (h << 7) + ch;
                    289:       ch = *cp++;
                    290:       if (ch != '\0') {
                    291:        h = (h << 7) + ch;
                    292:        ch = *cp++;
                    293:       }
                    294:     }
                    295:     h %= MAX_HASH;
                    296:   }
                    297:   return h;
                    298: }
                    299: 
                    300: 
                    301: nw_result nc_update(nw_update_type up_type, int *up_info) {
                    302:   nw_result rc;
                    303:   nw_alist_t ad;
                    304:   int h, slot, previous_slot, found_slot;
                    305:   nw_address_1 n1;
                    306:   nw_address_2 n2;
                    307: 
                    308:   if (up_type == NW_HOST_ADDRESS_REGISTER) {
                    309:     if (nw_free_address == -1) {
                    310:       rc = NW_NO_RESOURCES;
                    311:     } else {
                    312:       slot = nw_free_address;
                    313:       ad = &nw_address[slot];
                    314:       nw_free_address = ad->nw_next;
                    315:       ad->address = *((nw_address_t) up_info);
                    316:       h = nc_hash_name(ad->address.name);
                    317:       ad->name_next = nw_name[h];
                    318:       nw_name[h] = slot;
                    319:       h = ad->address.ip_addr % MAX_HASH;
                    320:       ad->ip_next = nw_ip[h];
                    321:       nw_ip[h] = slot;
                    322:       h = (ad->address.nw_addr_1 % MAX_HASH + ad->address.nw_addr_2)
                    323:              % MAX_HASH;
                    324:       ad->nw_next = nw_nw[h];
                    325:       nw_nw[h] = slot;
                    326:       ad->line = 0;
                    327:       rc = NW_SUCCESS;
                    328:     }
                    329:   } else if (up_type == NW_HOST_ADDRESS_UNREGISTER) {
                    330:     n1 = ((nw_address_t) up_info)->nw_addr_1;
                    331:     n2 = ((nw_address_t) up_info)->nw_addr_2;
                    332:     h = (n1 % MAX_HASH + n2) % MAX_HASH;
                    333:     slot = nw_nw[h];
                    334:     previous_slot = -1;
                    335:     ad = &nw_address[slot];
                    336:     while (slot != -1 && (ad->address.nw_addr_1 != n1 ||
                    337:                          ad->address.nw_addr_2 != n2)) {
                    338:       previous_slot = slot;
                    339:       slot = ad->nw_next;
                    340:       ad = &nw_address[slot];
                    341:     }
                    342:     if (slot == -1) {
                    343:       rc = NW_BAD_ADDRESS;
                    344:     } else {
                    345:       if (previous_slot == -1)
                    346:        nw_nw[h] = ad->nw_next;
                    347:       else
                    348:        nw_address[previous_slot].nw_next = ad->nw_next;
                    349:       ad->nw_next = nw_free_address;
                    350:       nw_free_address = slot;
                    351:       found_slot = slot;
                    352:       if (ad->address.ip_addr != 0) {
                    353:        h = ad->address.ip_addr % MAX_HASH;
                    354:        slot = nw_ip[h];
                    355:        previous_slot = -1;
                    356:        while (slot != -1 && slot != found_slot) {
                    357:          previous_slot = slot;
                    358:          slot = nw_address[slot].ip_next;
                    359:        }
                    360:        if (slot == found_slot) {
                    361:          if (previous_slot == -1)
                    362:            nw_ip[h] = ad->ip_next;
                    363:          else
                    364:            nw_address[previous_slot].ip_next = ad->ip_next;
                    365:        }
                    366:       }
                    367:       if (ad->address.name[0] != '\0') {
                    368:        h = nc_hash_name(ad->address.name);
                    369:        slot = nw_name[h];
                    370:        previous_slot = -1;
                    371:        while (slot != -1 && slot != found_slot) {
                    372:          previous_slot = slot;
                    373:          slot = nw_address[slot].name_next;
                    374:        }
                    375:        if (slot == found_slot) {
                    376:          if (previous_slot == -1)
                    377:            nw_name[h] = ad->name_next;
                    378:          else
                    379:            nw_address[previous_slot].name_next = ad->name_next;
                    380:        }
                    381:       }
                    382:       rc = NW_SUCCESS;
                    383:     }
                    384:   } else {
                    385:     rc = NW_INVALID_ARGUMENT;
                    386:   }
                    387:   return rc;
                    388: }
                    389: 
                    390: nw_result nc_lookup(nw_lookup_type lt, int *look_info) {
                    391:   nw_result rc;
                    392:   nw_address_t addr;
                    393:   nw_alist_t ad;
                    394:   int h, slot;
                    395:   ip_address ip;
                    396:   nw_address_1 n1;
                    397:   nw_address_2 n2;
                    398: 
                    399:   if (lt == NW_HOST_ADDRESS_LOOKUP) {
                    400:     addr = (nw_address_t) look_info;
                    401:     if (addr->ip_addr != 0) {
                    402:       ip = addr->ip_addr;
                    403:       h = ip % MAX_HASH;
                    404:       slot = nw_ip[h];
                    405:       ad = &nw_address[slot];
                    406:       while (slot != -1 && ad->address.ip_addr != ip) {
                    407:        slot = ad->ip_next;
                    408:        ad = &nw_address[slot];
                    409:       }
                    410:       if (slot != -1) {
                    411:        strcpy(addr->name, ad->address.name);
                    412:        addr->nw_addr_1 = ad->address.nw_addr_1;
                    413:        addr->nw_addr_2 = ad->address.nw_addr_2;
                    414:        return NW_SUCCESS;
                    415:       }
                    416:     }
                    417:     if (addr->name[0] != '\0') {
                    418:       h = nc_hash_name(addr->name);
                    419:       slot = nw_name[h];
                    420:       ad = &nw_address[slot];
                    421:       while (slot != -1 && strcmp(ad->address.name, addr->name) != 0) {
                    422:        slot = ad->name_next;
                    423:        ad = &nw_address[slot];
                    424:       }
                    425:       if (slot != -1) {
                    426:        addr->ip_addr = ad->address.ip_addr;
                    427:        addr->nw_addr_1 = ad->address.nw_addr_1;
                    428:        addr->nw_addr_2 = ad->address.nw_addr_2;
                    429:        return NW_SUCCESS;
                    430:       }
                    431:     }
                    432:     if (addr->nw_addr_1 != 0 || addr->nw_addr_2 != 0) {
                    433:       n1 = addr->nw_addr_1;
                    434:       n2 = addr->nw_addr_2;
                    435:       h = (n1 % MAX_HASH + n2) % MAX_HASH;
                    436:       slot = nw_nw[h];
                    437:       ad = &nw_address[slot];
                    438:       while (slot != -1 && (ad->address.nw_addr_1 != n1 ||
                    439:                            ad->address.nw_addr_2 != n2)) {
                    440:        slot = ad->nw_next;
                    441:        ad = &nw_address[slot];
                    442:       }
                    443:       if (slot != -1) {
                    444:        strcpy(addr->name, ad->address.name);
                    445:        addr->ip_addr = ad->address.ip_addr;
                    446:        return NW_SUCCESS;
                    447:       }
                    448:     }
                    449:     rc = NW_BAD_ADDRESS;
                    450:   } else {
                    451:     rc = NW_INVALID_ARGUMENT;
                    452:   }
                    453:   return rc;
                    454: }
                    455: 
                    456: nw_result nc_line_update(nw_peer_t peer, nw_ep line) {
                    457:   nw_result rc;
                    458:   nw_alist_t ad;
                    459:   int h, slot;
                    460:   nw_address_1 n1;
                    461:   nw_address_2 n2;
                    462: 
                    463:   n1 = peer->rem_addr_1;
                    464:   n2 = peer->rem_addr_2;
                    465:   h = (n1 % MAX_HASH + n2) % MAX_HASH;
                    466:   slot = nw_nw[h];
                    467:   ad = &nw_address[slot];
                    468:   while (slot != -1 && (ad->address.nw_addr_1 != n1 ||
                    469:                        ad->address.nw_addr_2 != n2)) {
                    470:     slot = ad->nw_next;
                    471:     ad = &nw_address[slot];
                    472:   }
                    473:   if (slot == -1) {
                    474:     rc = NW_FAILURE;
                    475:   } else {
                    476:     ad->line = line;
                    477:     rc = NW_SUCCESS;
                    478:   }
                    479:   return rc;
                    480: }
                    481: 
                    482: nw_ep nc_line_lookup(nw_peer_t peer) {
                    483:   nw_ep lep;
                    484:   nw_alist_t ad;
                    485:   int h, slot;
                    486:   nw_address_1 n1;
                    487:   nw_address_2 n2;
                    488: 
                    489:   n1 = peer->rem_addr_1;
                    490:   n2 = peer->rem_addr_2;
                    491:   h = (n1 % MAX_HASH + n2) % MAX_HASH;
                    492:   slot = nw_nw[h];
                    493:   ad = &nw_address[slot];
                    494:   while (slot != -1 && (ad->address.nw_addr_1 != n1 ||
                    495:                        ad->address.nw_addr_2 != n2)) {
                    496:     slot = ad->nw_next;
                    497:     ad = &nw_address[slot];
                    498:   }
                    499:   if (slot == -1) {
                    500:     lep = -1;
                    501:   } else {
                    502:     lep = ad->line;
                    503:   }
                    504:   return lep;
                    505: }
                    506: 
                    507: nw_result nc_endpoint_allocate(nw_ep_t epp, nw_protocol protocol,
                    508:                               nw_acceptance accept,
                    509:                               char *buffer_address, u_int buffer_size) {
                    510:   nw_result rc;
                    511:   nw_ep ep;
                    512:   nw_ecb_t ecb;
                    513: 
                    514:   if (ect[(ep = *epp)].state != NW_INEXISTENT) {
                    515:     rc = NW_BAD_EP;
                    516:   } else if (nw_free_ep_first == 0) {
                    517:     *epp = nw_free_line_first;
                    518:     rc = NW_NO_EP;
                    519:   } else {
                    520:     if (ep == 0) {
                    521:       ecb = &ect[nw_free_ep_first];
                    522:       *epp = ep = ecb->id;
                    523:       nw_free_ep_first = ecb->next;
                    524:       if (nw_free_ep_first == 0)
                    525:        nw_free_ep_last = 0;
                    526:     } else {
                    527:       ecb = &ect[ep];
                    528:       if (ecb->previous == 0)
                    529:        nw_free_ep_first = ecb->next;
                    530:       else
                    531:        ect[ecb->previous].next = ecb->next;
                    532:       if (ecb->next == 0)
                    533:        nw_free_ep_last = ecb->previous;
                    534:       else
                    535:        ect[ecb->next].previous = ecb->previous;
                    536:     }
                    537:     if (protocol == NW_LINE) {
                    538:       if (nw_free_line_last == 0)
                    539:        nw_free_line_first = ep;
                    540:       else
                    541:        ect[nw_free_line_last].next = ep;
                    542:       ecb->previous = nw_free_line_last;
                    543:       ecb->next = 0;
                    544:       nw_free_line_last = ep;
                    545:     }
                    546:     ecb->protocol = protocol;
                    547:     ecb->accept = accept;
                    548:     ecb->state = NW_UNCONNECTED;
                    549:     ecb->conn = NULL;
                    550:     ecb->buf_start = buffer_address;
                    551:     ecb->buf_end = buffer_address + buffer_size;
                    552:     ecb->free_buffer = (nw_unused_buffer_t) buffer_address;
                    553:     ecb->free_buffer->buf_used = 0;
                    554:     ecb->free_buffer->buf_length = buffer_size;
                    555:     ecb->free_buffer->previous = NULL;
                    556:     ecb->free_buffer->next = NULL;
                    557:     ecb->overrun = 0;
                    558:     ecb->seqno = 0;
                    559:     ecb->tx_first = NULL;
                    560:     ecb->tx_last = NULL;
                    561:     ecb->tx_initial = NULL;
                    562:     ecb->tx_current = NULL;
                    563:     ecb->rx_first = NULL;
                    564:     ecb->rx_last = NULL;
                    565:     rc = NW_SUCCESS;
                    566:   }
                    567:   return rc;
                    568: }
                    569: 
                    570: nw_result nc_endpoint_deallocate(nw_ep ep) {
                    571:   nw_ecb_t ecb;
                    572:   nw_rx_header_t rx_header;
                    573: 
                    574:   ecb = &ect[ep];
                    575:   if (ecb->conn != NULL) 
                    576:     nc_peer_deallocate(ecb->conn);
                    577:   if (ecb->tx_first != NULL)
                    578:     nc_tx_header_deallocate(ecb->tx_first);
                    579:   if (ecb->tx_initial != NULL)
                    580:     nc_tx_header_deallocate(ecb->tx_initial);
                    581:   while (ecb->rx_first != NULL) {
                    582:     rx_header = ecb->rx_first;
                    583:     ecb->rx_first = rx_header->next;
                    584:     nc_rx_header_deallocate(rx_header);
                    585:   }
                    586:   if (ecb->protocol == NW_LINE) {
                    587:     if (ecb->previous == 0)
                    588:       nw_free_line_first = ecb->next;
                    589:     else
                    590:       ect[ecb->previous].next = ecb->next;
                    591:     if (ecb->next == 0)
                    592:       nw_free_line_last = ecb->previous;
                    593:     else
                    594:       ect[ecb->next].previous = ecb->previous;
                    595:   }
                    596:   ecb->next = 0;
                    597:   ecb->previous = nw_free_ep_last;
                    598:   if (nw_free_ep_last == 0)
                    599:     nw_free_ep_first = ep;
                    600:   else
                    601:     ect[nw_free_ep_last].next = ep;
                    602:   nw_free_ep_last = ep;
                    603:   ecb->id = ep;
                    604:   ecb->state = NW_INEXISTENT;
                    605:   return NW_SUCCESS;
                    606: }
                    607: 
                    608: void nc_buffer_coalesce(nw_ecb_t ecb) {
                    609:   nw_unused_buffer_t p, q, buf_free, buf_start, buf_end;
                    610: 
                    611:   buf_start = p = (nw_unused_buffer_t) ecb->buf_start;
                    612:   buf_end = (nw_unused_buffer_t) ecb->buf_end;
                    613:   buf_free = NULL;
                    614:   while (p >= buf_start && p < buf_end) {
                    615:     if (p->buf_length & 0x3)
                    616:       goto trash_area;
                    617:     if (p->buf_used) {
                    618:       p = (nw_unused_buffer_t) ((char *) p + p->buf_length);
                    619:     } else {
                    620:       q = (nw_unused_buffer_t) ((char *) p + p->buf_length);
                    621:       while (q >= buf_start && q < buf_end && !q->buf_used) {
                    622:        if (q->buf_length & 0x3)
                    623:          goto trash_area;
                    624:        p->buf_length += q->buf_length;
                    625:        q = (nw_unused_buffer_t) ((char *) q + q->buf_length);
                    626:       }
                    627:       p->next = buf_free;
                    628:       p->previous = NULL;
                    629:       if (buf_free != NULL)
                    630:        buf_free->previous = p;
                    631:       buf_free = p;
                    632:       p = q;
                    633:     }
                    634:   }
                    635:   ecb->free_buffer = buf_free;
                    636:   return;
                    637: 
                    638:  trash_area:
                    639:   ecb->free_buffer = NULL;
                    640:   return;
                    641: }
                    642: 
                    643:   
                    644: nw_buffer_t nc_buffer_allocate(nw_ep ep, u_int size) {
                    645:   nw_ecb_t ecb;
                    646:   nw_unused_buffer_t buf, buf_start, buf_end;
                    647: 
                    648:   ecb = &ect[ep];
                    649:   buf_start = (nw_unused_buffer_t) ecb->buf_start;
                    650:   buf_end = (nw_unused_buffer_t) (ecb->buf_end - sizeof(nw_buffer_s));
                    651:   if (size < sizeof(nw_buffer_s))
                    652:     size = sizeof(nw_buffer_s);
                    653:   else
                    654:     size = ((size + 3) >> 2) << 2;
                    655:   buf = ecb->free_buffer;
                    656:   if (buf != NULL) {
                    657:     while (buf->buf_length < size) {
                    658:       buf = buf->next;
                    659:       if (buf < buf_start || buf > buf_end || ((int) buf & 0x3)) {
                    660:        buf = NULL;
                    661:        break;
                    662:       }
                    663:     }
                    664:   }
                    665:   if (buf == NULL) {
                    666:     nc_buffer_coalesce(ecb);
                    667:     buf = ecb->free_buffer;
                    668:     while (buf != NULL && buf->buf_length < size)
                    669:       buf = buf->next;
                    670:   }
                    671:   if (buf == NULL) {
                    672:     ecb->overrun = 1;
                    673:   } else {
                    674:     if (buf->buf_length < size + sizeof(nw_buffer_s)) {
                    675:       if (buf->previous == NULL)
                    676:        ecb->free_buffer = buf->next;
                    677:       else
                    678:        buf->previous->next = buf->next;
                    679:       if (buf->next != NULL)
                    680:        buf->next->previous = buf->previous;
                    681:     } else {
                    682:       buf->buf_length -= size;
                    683:       buf = (nw_unused_buffer_t) ((char *) buf + buf->buf_length);
                    684:       buf->buf_length = size;
                    685:     }
                    686:     buf->buf_used = 1;
                    687:   }
                    688:   return (nw_buffer_t) buf;
                    689: }
                    690: 
                    691: nw_result nc_buffer_deallocate(nw_ep ep, nw_buffer_t buffer) {
                    692:   nw_ecb_t ecb;
                    693:   nw_unused_buffer_t buf;
                    694: 
                    695:   ecb = &ect[ep];
                    696:   buf = (nw_unused_buffer_t) buffer;
                    697:   buf->buf_used = 0;
                    698:   buf->previous = NULL;
                    699:   buf->next = ecb->free_buffer;
                    700:   if (ecb->free_buffer != NULL)
                    701:     ecb->free_buffer->previous = buf;
                    702:   ecb->free_buffer = buf;
                    703:   return NW_SUCCESS;
                    704: }
                    705: 
                    706: nw_result nc_endpoint_status(nw_ep ep, nw_state_t state, nw_peer_t peer) {
                    707:   nw_result rc;
                    708:   nw_ecb_t ecb;
                    709: 
                    710:   ecb = &ect[ep];
                    711:   *state = ecb->state;
                    712:   if (ecb->conn)
                    713:     *peer = ecb->conn->peer;
                    714:   if (ecb->overrun) {
                    715:     ecb->overrun = 0;
                    716:     rc = NW_OVERRUN;
                    717:   } else if (ecb->rx_first != NULL) {
                    718:     rc = NW_QUEUED;
                    719:   } else {
                    720:     rc = NW_SUCCESS;
                    721:   }
                    722:   return rc;
                    723: }
                    724: 
                    725: 
                    726: nw_result nc_local_send(nw_ep ep, nw_tx_header_t header, nw_options options) {
                    727:   nw_result rc;
                    728:   nw_ep receiver;
                    729:   int length;
                    730:   nw_buffer_t buffer;
                    731:   nw_tx_header_t first_header;
                    732:   nw_rx_header_t rx_header;
                    733:   char *bufp;
                    734:   nw_ecb_t ecb;
                    735: 
                    736:   receiver = header->peer.remote_ep;
                    737:   length = header->msg_length;
                    738:   buffer = nc_buffer_allocate(receiver, sizeof(nw_buffer_s) + length);
                    739:   if (buffer == NULL) {
                    740:     rc = NW_OVERRUN;
                    741:   } else {
                    742:     buffer->buf_next = NULL;
                    743:     buffer->block_offset = sizeof(nw_buffer_s);
                    744:     buffer->block_length = length;
                    745:     buffer->peer.rem_addr_1 = NW_NULL << 28;
                    746:     buffer->peer.rem_addr_2 = 0;
                    747:     buffer->peer.remote_ep = ep;
                    748:     buffer->peer.local_ep = receiver;
                    749:     bufp = (char *) buffer + sizeof(nw_buffer_s);
                    750:     first_header = header;
                    751:     while (header != NULL) {
                    752:       length = header->block_length;
                    753:       bcopy(header->block, bufp, length);
                    754:       bufp += length;
                    755:       if (header->buffer != NULL) 
                    756:        nc_buffer_deallocate(ep, header->buffer);
                    757:       header = header->next;
                    758:     }
                    759:     nc_tx_header_deallocate(first_header);
                    760:     ecb = &ect[receiver];
                    761:     if (options == NW_URGENT) {
                    762:       buffer->msg_seqno = 0;
                    763:       if (nc_deliver_result(receiver, NW_RECEIVE_URGENT, (int) buffer))
                    764:        rc = NW_SUCCESS;
                    765:       else
                    766:        rc = NW_NO_RESOURCES;
                    767:     } else {
                    768:       if (ecb->seqno == 1023)
                    769:        buffer->msg_seqno = ecb->seqno = 1;
                    770:       else
                    771:        buffer->msg_seqno = ++ecb->seqno;
                    772:       if (nc_deliver_result(receiver, NW_RECEIVE, (int) buffer)) 
                    773:        rc = NW_SUCCESS;
                    774:       else
                    775:        rc = NW_NO_RESOURCES;
                    776:     }
                    777:   }
                    778:   return rc;
                    779: }
                    780: 
                    781: nw_buffer_t nc_local_rpc(nw_ep ep, nw_tx_header_t header, nw_options options) {
                    782:   nw_buffer_t buf;
                    783:   nw_ecb_t ecb;
                    784:   nw_rx_header_t rx_header;
                    785: 
                    786:   ecb = &ect[ep];
                    787:   rx_header = ecb->rx_first;
                    788:   if (nc_local_send(ep, header, options) != NW_SUCCESS) {
                    789:     buf = NW_BUFFER_ERROR;
                    790:   } else if (rx_header == NULL) {
                    791:     buf = NULL;
                    792:   } else {
                    793:     buf = rx_header->buffer;
                    794:     ecb->rx_first = rx_header->next;
                    795:     if (ecb->rx_first == NULL)
                    796:       ecb->rx_last = NULL;
                    797:     nc_rx_header_deallocate(rx_header);
                    798:   }
                    799:   return buf;
                    800: }
                    801:                         
                    802: 
                    803: nw_result nc_succeed(int dev) {
                    804: 
                    805:   return NW_SUCCESS;
                    806: }
                    807:                              
                    808: void nc_null(int dev) {
                    809: 
                    810: }
                    811: 
                    812: nw_result nc_fail(int dev) {
                    813: 
                    814:   return NW_FAILURE;
                    815: }
                    816: 
                    817: int nc_null_poll(int dev) {
                    818:   
                    819:   return 1000000;
                    820: }
                    821: 
                    822: nw_result nc_null_send(nw_ep ep, nw_tx_header_t header, nw_options options) {
                    823: 
                    824:   return NW_FAILURE;
                    825: }
                    826: 
                    827: nw_buffer_t nc_null_rpc(nw_ep ep, nw_tx_header_t header, nw_options options) {
                    828: 
                    829:   return NW_BUFFER_ERROR;
                    830: }
                    831: 
                    832: void nc_null_signal(nw_buffer_t msg) {
                    833: 
                    834: }
                    835: 
                    836: nw_result nc_open_fail(nw_ep lep, nw_address_1 a1,
                    837:                       nw_address_2 a2, nw_ep rep) {
                    838: 
                    839:   return NW_FAILURE;
                    840: }
                    841: 
                    842: nw_result nc_close_fail(nw_ep ep) {
                    843: 
                    844:   return NW_FAILURE;
                    845: }
                    846: 
                    847: nw_result nc_accept_fail(nw_ep ep, nw_buffer_t msg, nw_ep_t epp) {
                    848: 
                    849:   return NW_FAILURE;
                    850: }
                    851: 

unix.superglobalmegacorp.com

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