|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.