| 2408 | | netinput() |
| 2409 | | { |
| 2410 | | struct sockaddr_in osad; |
| 2411 | | #ifdef SOCKLENISUINT |
| 2412 | | #if defined(IMA_AIX4SP2) || defined(IMA_AIX5SP2) \ |
| 2413 | | || defined(IMA_AIX56K64) || defined(IMA_LINUXALPHA) |
| 2414 | | unsigned int oslen; |
| 2415 | | #else |
| 2416 | | size_t oslen; |
| 2417 | | #endif |
| 2418 | | #else |
| | | ... |
| 2429 | | int src; |
| 2430 | | int hh; |
| 2431 | | int already; |
| 2432 | | struct timeval tdiff; |
| 2433 | | int rttusec; |
| 2434 | | |
| 2435 | | |
| 2436 | | |
| 2437 | | |
| 2438 | | |
| 2439 | | pp = pk_new(pvmudpmtu); |
| 2440 | | if (TDFRAGHDR > DDFRAGHDR)
|
| 2441 | | pp->pk_dat += TDFRAGHDR - DDFRAGHDR;
|
| 2442 | | |
| 2443 | | oslen = sizeof(osad); |
| 2444 | | if ((pp->pk_len = recvfrom(netsock, pp->pk_dat, |
| 2445 | | pp->pk_max - (pp->pk_dat - pp->pk_buf), |
| 2446 | | 0, (struct sockaddr*)&osad, &oslen)) == -1) { |
| 2447 | | if (errno != EINTR)
|
| 2448 | | pvmlogperror("netinput() recvfrom(netsock)"); |
| 2449 | | goto scrap; |
| 2450 | | } |
| 2451 | | |
| 2452 | | #if 0 |
| 2453 | | |
| 2454 | | if (!(random() & 3)) { |
| 2455 | | pvmlogerror("netinput() oops, dropped one\n"); |
| 2456 | | goto scrap; |
| 2457 | | } |
| 2458 | | #endif |
| 2459 | | |
| 2460 | | #ifdef STATISTICS |
| 2461 | | stats.rfok++; |
| 2462 | | #endif |
| 2463 | | |
| 2464 | | cp = pp->pk_dat; |
| 2465 | | pp->pk_len -= DDFRAGHDR;
|
| 2466 | | pp->pk_dat += DDFRAGHDR;
|
| 2467 | | dst = pp->pk_dst = pvmget32(cp); |
| 2468 | | src = pp->pk_src = pvmget32(cp + 4); |
| 2469 | | sqn = pp->pk_seq = pvmget16(cp + 8); |
| 2470 | | aqn = pvmget16(cp + 10); |
| 2471 | | ff = pp->pk_flag = pvmget8(cp + 12); |
| 2472 | | if (ff & FFSOM) {
|
| 2473 | | if (pp->pk_len < MSGHDRLEN) {
|
| 2474 | | pvmlogprintf("netinput() SOM pkt src t%x dst t%x too short\n", |
| 2475 | | src, dst); |
| 2476 | | goto scrap; |
| 2477 | | } |
| 2478 | | cp += DDFRAGHDR;
|
| 2479 | | pp->pk_enc = pvmget32(cp); |
| 2480 | | pp->pk_tag = pvmget32(cp + 4); |
| 2481 | | pp->pk_ctx = pvmget32(cp + 8); |
| 2482 | | pp->pk_wid = pvmget32(cp + 16); |
| 2483 | | pp->pk_crc = pvmget32(cp + 20); |
| 2484 | | pp->pk_len -= MSGHDRLEN;
|
| 2485 | | pp->pk_dat += MSGHDRLEN;
|
| 2486 | | } |
| 2487 | | |
| 2488 | | |
| 2489 | | |
| 2490 | | |
| 2491 | | |
| 2492 | | hh = (src & tidhmask) >> (ffs(tidhmask) - 1); |
| 2493 | | if (hh < 0 || hh > hosts->ht_last || !(hp = hosts->ht_hosts[hh]) |
| 2494 | | |
| 2495 | | |
| 2496 | | |
| 2497 | | |
| 2498 | | |
| 2499 | | |
| 2500 | | || (osad.sin_addr.s_addr != hp->hd_sad.sin_addr.s_addr) |
| 2501 | | || (osad.sin_port != hp->hd_sad.sin_port) |
| 2502 | | |
| 2503 | | ) { |
| 2504 | | pvmlogprintf("netinput() bogus pkt from %s\n", |
| 2505 | | inadport_decimal(&osad)); |
| 2506 | | goto scrap; |
| 2507 | | } |
| 2508 | | |
| 2509 | | if (pvmdebmask & PDMPACKET) {
|
| 2510 | | pvmlogprintf( |
| 2511 | | "netinput() pkt from %s src t%x dst t%x f %s len %d seq %d ack %d\n", |
| 2512 | | hp->hd_name, src, dst, pkt_flags(ff), pp->pk_len, sqn, aqn); |
| 2513 | | } |
| 2514 | | |
| 2515 | | if ((ff & (FFFIN|FFACK)) == (FFFIN|FFACK)) {
|
| 2516 | | if (hh == hosts->ht_master) { |
| 2517 | | |
| 2518 | | |
| 2519 | | |
| 2520 | | if (runstate == PVMDPRIME) {
|
| 2521 | | if (pvmdebmask & PDMSTARTUP)
|
| 2522 | | pvmlogerror("work() PVMDPRIME halting\n"); |
| 2523 | | exit(0); |
| 2524 | | } |
| 2525 | | pvmlogprintf("netinput() FIN|ACK from master (%s)\n", |
| 2526 | | hp->hd_name); |
| 2527 | | runstate = PVMDHALTING;
|
| 2528 | | |
| 2529 | | } else { |
| 2530 | | |
| 2531 | | |
| 2532 | | |
| 2533 | | pvmlogprintf("netinput() FIN|ACK from %s\n", |
| 2534 | | hp->hd_name); |
| 2535 | | hd_dump(hp); |
| 2536 | | hostfailentry(hp); |
| 2537 | | clear_opq_of((int)(TIDPVMD | hp->hd_hostpart));
|
| 2538 | | if (hp->hd_hostpart) { |
| 2539 | | ht_delete(hosts, hp); |
| 2540 | | if (newhosts) |
| 2541 | | ht_delete(newhosts, hp); |
| 2542 | | } |
| 2543 | | } |
| 2544 | | goto scrap; |
| 2545 | | } |
| 2546 | | |
| 2547 | | |
| 2548 | | |
| 2549 | | |
| 2550 | | |
| 2551 | | if (ff & FFACK) {
|
| 2552 | | for (pp2 = hp->hd_opq->pk_link; pp2 != hp->hd_opq; pp2 = pp2->pk_link) |
| 2553 | | if (pp2->pk_seq == aqn) { |
| 2554 | | if (pp2->pk_flag & FFDAT) {
|
| 2555 | | if (pp2->pk_nrt == 1) { |
| 2556 | | pvmgetclock(&tnow); |
| 2557 | | |
| 2558 | | TVXSUBY(&tdiff, &tnow, &pp2->pk_at);
|
| 2559 | | rttusec = tdiff.tv_sec * 1000000 + tdiff.tv_usec; |
| 2560 | | if (rttusec < 1) |
| 2561 | | rttusec = 1000; |
| 2562 | | else |
| 2563 | | if (rttusec > DDMAXRTT*1000000)
|
| 2564 | | rttusec = DDMAXRTT*1000000;
|
| 2565 | | rttusec += 3 * (hp->hd_rtt.tv_sec * 1000000 + hp->hd_rtt.tv_usec); |
| 2566 | | rttusec /= 4; |
| 2567 | | hp->hd_rtt.tv_sec = rttusec / 1000000; |
| 2568 | | hp->hd_rtt.tv_usec = rttusec % 1000000; |
| 2569 | | } |
| 2570 | | } |
| 2571 | | if (pp2->pk_flag & FFFIN) {
|
| 2572 | | finack_to_host(hp); |
| 2573 | | } |
| 2574 | | hp->hd_nop--; |
| 2575 | | LISTDELETE(pp2, pk_link, pk_rlink);
|
| 2576 | | pk_free(pp2); |
| 2577 | | break; |
| 2578 | | } |
| 2579 | | } |
| 2580 | | |
| 2581 | | |
| 2582 | | |
| 2583 | | |
| 2584 | | |
| 2585 | | |
| 2586 | | |
| 2587 | | |
| 2588 | | if (hp->hd_nop < nopax |
| 2589 | | && (hp->hd_txq->pk_link != hp->hd_txq)) { |
| 2590 | | if (pvmdebmask & PDMPACKET) {
|
| 2591 | | pvmlogprintf("netinput() pkt to opq\n"); |
| 2592 | | } |
| 2593 | | pp2 = hp->hd_txq->pk_link; |
| 2594 | | LISTDELETE(pp2, pk_link, pk_rlink);
|
| 2595 | | TVCLEAR(&pp2->pk_rtv);
|
| 2596 | | TVXADDY(&pp2->pk_rta, &hp->hd_rtt, &hp->hd_rtt);
|
| 2597 | | TVCLEAR(&pp2->pk_rto);
|
| 2598 | | TVCLEAR(&pp2->pk_at);
|
| 2599 | | pp2->pk_nrt = 0; |
| 2600 | | pp2->pk_hostd = hp; |
| 2601 | | pp2->pk_seq = hp->hd_txseq; |
| 2602 | | hp->hd_txseq = NEXTSEQNUM(hp->hd_txseq);
|
| 2603 | | LISTPUTBEFORE(hp->hd_opq, pp2, pk_link, pk_rlink);
|
| 2604 | | hp->hd_nop++; |
| 2605 | | LISTPUTBEFORE(opq, pp2, pk_tlink, pk_trlink);
|
| 2606 | | } |
| 2607 | | |
| 2608 | | if (!(ff & (FFDAT|FFFIN)))
|
| 2609 | | goto scrap; |
| 2610 | | |
| 2611 | | |
| 2612 | | |
| 2613 | | |
| 2614 | | |
| 2615 | | pp2 = pk_new(DDFRAGHDR);
|
| 2616 | | pp2->pk_dat += DDFRAGHDR;
|
| 2617 | | pp2->pk_dst = hp->hd_hostpart | TIDPVMD;
|
| 2618 | | pp2->pk_src = pvmmytid; |
| 2619 | | pp2->pk_flag = FFACK;
|
| 2620 | | TVCLEAR(&pp2->pk_rtv);
|
| 2621 | | TVCLEAR(&pp2->pk_rta);
|
| 2622 | | TVCLEAR(&pp2->pk_rto);
|
| 2623 | | TVCLEAR(&pp2->pk_at);
|
| 2624 | | pp2->pk_nrt = 0; |
| 2625 | | pp2->pk_hostd = hp; |
| 2626 | | pp2->pk_seq = 0; |
| 2627 | | pp2->pk_ack = sqn; |
| 2628 | | |
| 2629 | | |
| 2630 | | |
| 2631 | | |
| 2632 | | |
| 2633 | | |
| 2634 | | |
| 2635 | | { |
| 2636 | | struct pkt *pp3; |
| 2637 | | for (pp3 = opq->pk_tlink; pp3 != opq; pp3 = pp3->pk_tlink) |
| 2638 | | if (TVXLTY(&pp2->pk_rtv, &pp3->pk_rtv))
|
| 2639 | | break; |
| 2640 | | LISTPUTBEFORE(pp3, pp2, pk_tlink, pk_trlink);
|
| 2641 | | } |
| 2642 | | |
| 2643 | | if (!(ff & FFDAT))
|
| 2644 | | goto scrap; |
| 2645 | | |
| 2646 | | |
| 2647 | | |
| 2648 | | |
| 2649 | | |
| 2650 | | pp2 = 0; |
| 2651 | | if (SEQLESSTHAN(sqn, hp->hd_rxseq))
|
| 2652 | | already = 1; |
| 2653 | | else { |
| 2654 | | already = 0; |
| 2655 | | for (pp2 = hp->hd_rxq->pk_link; pp2 != hp->hd_rxq; pp2 = pp2->pk_link) |
| 2656 | | if (!SEQLESSTHAN(pp2->pk_seq,sqn)) {
|
| 2657 | | if (pp2->pk_seq == sqn) |
| 2658 | | already = 1; |
| 2659 | | break; |
| 2660 | | } |
| 2661 | | } |
| 2662 | | if (already) { |
| 2663 | | if (pvmdebmask & PDMPACKET) {
|
| 2664 | | pvmlogprintf("netinput() pkt resent from %s seq %d\n", |
| 2665 | | hp->hd_name, sqn); |
| 2666 | | } |
| 2667 | | goto scrap; |
| 2668 | | } |
| 2669 | | |
| 2670 | | LISTPUTBEFORE(pp2, pp, pk_link, pk_rlink);
|
| 2671 | | |
| 2672 | | |
| 2673 | | |
| 2674 | | |
| 2675 | | |
| 2676 | | while (pp = hp->hd_rxq->pk_link, |
| 2677 | | pp != hp->hd_rxq && pp->pk_seq == hp->hd_rxseq) { |
| 2678 | | hp->hd_rxseq = NEXTSEQNUM(hp->hd_rxseq);
|
| 2679 | | LISTDELETE(pp, pk_link, pk_rlink);
|
| 2680 | | netinpkt(hp, pp); |
| 2681 | | } |
| 2682 | | return 0; |
| 2683 | | |
| 2684 | | scrap: |
| 2685 | | if (pp) |
| 2686 | | pk_free(pp); |
| 2687 | | return 0; |
| 2688 | | } |