github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/transport/internet/websocket/connforwarder.go (about)

     1  package websocket
     2  
     3  import (
     4  	"context"
     5  	"io"
     6  	"net"
     7  	"time"
     8  )
     9  
    10  type connectionForwarder struct {
    11  	io.ReadWriteCloser
    12  
    13  	shouldWait        bool
    14  	delayedDialFinish context.Context
    15  	finishedDial      context.CancelFunc
    16  	dialer            DelayedDialerForwarded
    17  }
    18  
    19  func (c *connectionForwarder) Read(p []byte) (n int, err error) {
    20  	if c.shouldWait {
    21  		<-c.delayedDialFinish.Done()
    22  		if c.ReadWriteCloser == nil {
    23  			return 0, newError("unable to read delayed dial websocket connection as it do not exist")
    24  		}
    25  	}
    26  	return c.ReadWriteCloser.Read(p)
    27  }
    28  
    29  func (c *connectionForwarder) Write(p []byte) (n int, err error) {
    30  	if c.shouldWait {
    31  		var err error
    32  		c.ReadWriteCloser, err = c.dialer.Dial(p)
    33  		c.finishedDial()
    34  		if err != nil {
    35  			return 0, newError("Unable to proceed with delayed write").Base(err)
    36  		}
    37  		c.shouldWait = false
    38  		return len(p), nil
    39  	}
    40  	return c.ReadWriteCloser.Write(p)
    41  }
    42  
    43  func (c *connectionForwarder) Close() error {
    44  	if c.shouldWait {
    45  		<-c.delayedDialFinish.Done()
    46  		if c.ReadWriteCloser == nil {
    47  			return newError("unable to close delayed dial websocket connection as it do not exist")
    48  		}
    49  	}
    50  	return c.ReadWriteCloser.Close()
    51  }
    52  
    53  func (c connectionForwarder) LocalAddr() net.Addr {
    54  	return &net.UnixAddr{
    55  		Name: "not available",
    56  		Net:  "",
    57  	}
    58  }
    59  
    60  func (c connectionForwarder) RemoteAddr() net.Addr {
    61  	return &net.UnixAddr{
    62  		Name: "not available",
    63  		Net:  "",
    64  	}
    65  }
    66  
    67  func (c connectionForwarder) SetDeadline(t time.Time) error {
    68  	return nil
    69  }
    70  
    71  func (c connectionForwarder) SetReadDeadline(t time.Time) error {
    72  	return nil
    73  }
    74  
    75  func (c connectionForwarder) SetWriteDeadline(t time.Time) error {
    76  	return nil
    77  }
    78  
    79  type DelayedDialerForwarded interface {
    80  	Dial(earlyData []byte) (io.ReadWriteCloser, error)
    81  }