Annotation of Gnu-Mach/chips/nc.c, revision 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.