- select($readfds=$wantreadfds,'','',$thistimeout);
- for (;;) {
- if (!defined($r= sysread(UR,$upbuf,$mtu*2+3,length($upbuf)))) {
- $! == EAGAIN || warning("tunnel endpoint read error: $!");
- last;
- }
- if (!$r) {
- quit "tunnel endpoint closed by system";
- }
- while (($p= index($upbuf,"\300")) >= 0) {
- if ($p && !defined(send L,substr($upbuf,0,$p),0,$rs)) {
- warning("transmit error: $!");
- } else {
- if (!$upyet) {
- $upyet= 1;
- debug($downyet ? "tunnel open at this end" : "transmitting");
- }
- if ($keepalive) { $nextsendka= now()+$keepalive; }
- }
- $upbuf= substr($upbuf,$p+1);
- }
- }
- while (defined($rs_from= recv L,$downbuf,$mtu*2+3,0)) {
- $rsp_from= show_addr_port($rs_from);
- if ($rsp_from ne $rsp) {
- warning("got packet from incorrect peer $rsp_from");
- next;
- }
- $downbuf= "\300".$downbuf."\300";
- if (!defined($r= syswrite(DW,$downbuf,length $downbuf))) {
- warning("tunnel endpoint write error: $!");
- } elsif ($r != length $downbuf) {
- warning("tunnel endpoint wrong write length");
- } else {
- if (!$downyet) {
- $downyet= 1;
- debug($upyet ? "tunnel open at this end" : "receiving");
- }
- alarm($timeout) if $timeout;
- }
- }
- if ($! == ECONNREFUSED) { quit("tunnel closed at remote end"); }
- $! == EAGAIN || warning("receive error: $!");