@@ -13,7 +13,6 @@ import (
1313 "math"
1414 "math/big"
1515 "net"
16- "sync"
1716 "time"
1817
1918 "github.com/libraries/daze"
@@ -107,7 +106,7 @@ func (s *Stream) Write(p []byte) (int, error) {
107106// Server implemented the ashe-over-quic protocol.
108107type Server struct {
109108 Cipher []byte
110- Ep * quic.Endpoint
109+ EpQuic * quic.Endpoint
111110 Limits * rate.Limits
112111 Listen string
113112}
@@ -120,25 +119,25 @@ func (s *Server) Serve(ctx *daze.Context, cli io.ReadWriteCloser) error {
120119
121120// Close listener. Established connections will not be closed.
122121func (s * Server ) Close () error {
123- if s .Ep != nil {
124- return s .Ep .Close (context .Background ())
122+ if s .EpQuic != nil {
123+ return s .EpQuic .Close (context .Background ())
125124 }
126125 return nil
127126}
128127
129128// Run it.
130129func (s * Server ) Run () error {
131- ep , err := quic .Listen ("udp" , s .Listen , ServerConfig .Do ())
130+ l , err := quic .Listen ("udp" , s .Listen , ServerConfig .Do ())
132131 if err != nil {
133132 return err
134133 }
135- s .Ep = ep
134+ s .EpQuic = l
136135 log .Println ("main: listen and serve on" , s .Listen )
137136
138137 go func () {
139138 idx := uint32 (math .MaxUint32 )
140139 for {
141- con , err := ep .Accept (context .Background ())
140+ con , err := l .Accept (context .Background ())
142141 if err != nil {
143142 if ! errors .Is (err , context .Canceled ) && ! errors .Is (err , net .ErrClosed ) {
144143 log .Println ("main:" , err )
@@ -147,16 +146,16 @@ func (s *Server) Run() error {
147146 }
148147 go func (con * quic.Conn ) {
149148 defer con .Close ()
150- peer := net .UDPAddrFromAddrPort (con .RemoteAddr ())
149+ rem := net .UDPAddrFromAddrPort (con .RemoteAddr ())
151150 for {
152151 stm , err := con .AcceptStream (context .Background ())
153152 if err != nil {
154153 return
155154 }
156155 idx ++
157156 ctx := & daze.Context {Cid : idx }
158- cli := & Stream {rem : peer , stm : stm }
159- log .Printf ("conn: %08x accept remote=%s" , ctx .Cid , peer )
157+ cli := & Stream {rem : rem , stm : stm }
158+ log .Printf ("conn: %08x accept remote=%s" , ctx .Cid , rem )
160159 rtc := & daze.ReadWriteCloser {
161160 Reader : io .TeeReader (cli , rate .NewLimitsWriter (s .Limits )),
162161 Writer : io .MultiWriter (cli , rate .NewLimitsWriter (s .Limits )),
@@ -189,56 +188,27 @@ func NewServer(listen string, cipher string) *Server {
189188// Client implemented the ashe-over-quic protocol.
190189type Client struct {
191190 Cipher []byte
191+ EpQuic * quic.Endpoint
192192 Server string
193-
194- mu sync.Mutex
195- ep * quic.Endpoint
196- }
197-
198- // endpoint lazily creates the shared quic endpoint that originates outbound connections. A single endpoint can
199- // originate many connections, so reusing it avoids burning a new udp socket for every Dial.
200- func (c * Client ) endpoint () (* quic.Endpoint , error ) {
201- c .mu .Lock ()
202- defer c .mu .Unlock ()
203- if c .ep != nil {
204- return c .ep , nil
205- }
206- // The client endpoint also needs a tls config that satisfies the "certificate or GetCertificate" requirement of
207- // quic.Listen even though the endpoint never accepts inbound connections.
208- ep , err := quic .Listen ("udp" , ":0" , ClientConfig .Do ())
209- if err != nil {
210- return nil , err
211- }
212- c .ep = ep
213- return ep , nil
214193}
215194
216- // Estab dials the etch server and establishes an ashe channel over it. It is the caller's responsibility to close the
217- // returned conn.
218- func (c * Client ) Estab (ctx * daze.Context , network string , address string ) (io.ReadWriteCloser , error ) {
219- ep , err := c .endpoint ()
220- if err != nil {
221- return nil , err
222- }
223- dialCtx , cancel := context .WithTimeout (context .Background (), daze .Conf .DialerTimeout )
224- defer cancel ()
225- con , err := ep .Dial (dialCtx , "udp" , c .Server , ClientConfig .Do ())
195+ // Dial connects to the address on the named network.
196+ func (c * Client ) Dial (ctx * daze.Context , network string , address string ) (io.ReadWriteCloser , error ) {
197+ con , err := c .EpQuic .Dial (context .Background (), "udp" , c .Server , ClientConfig .Do ())
226198 if err != nil {
227199 return nil , err
228200 }
229- stm , err := con .NewStream (dialCtx )
201+ stm , err := con .NewStream (context . Background () )
230202 if err != nil {
231203 con .Close ()
232204 return nil , err
233205 }
234- // NewStream is lazy: the peer does not see the stream until the first byte is written. Force a flush so the
235- // server's AcceptStream returns promptly even if the ashe client decides to read before writing.
236206 if err := stm .Flush (); err != nil {
237207 con .Close ()
238208 return nil , err
239209 }
240- addr := net .UDPAddrFromAddrPort (con .RemoteAddr ())
241- srv := & Stream {con : con , rem : addr , stm : stm }
210+ rem := net .UDPAddrFromAddrPort (con .RemoteAddr ())
211+ srv := & Stream {con : con , rem : rem , stm : stm }
242212 spy := & ashe.Client {Cipher : c .Cipher }
243213 out , err := spy .Estab (ctx , srv , network , address )
244214 if err != nil {
@@ -248,15 +218,11 @@ func (c *Client) Estab(ctx *daze.Context, network string, address string) (io.Re
248218 return out , nil
249219}
250220
251- // Dial connects to the address on the named network.
252- func (c * Client ) Dial (ctx * daze.Context , network string , address string ) (io.ReadWriteCloser , error ) {
253- return c .Estab (ctx , network , address )
254- }
255-
256221// NewClient returns a new Client. Cipher is a password in string form, with no length limit.
257222func NewClient (server string , cipher string ) * Client {
258223 return & Client {
259224 Cipher : daze .Salt (cipher ),
225+ EpQuic : doa .Try (quic .Listen ("udp" , ":0" , ClientConfig .Do ())),
260226 Server : server ,
261227 }
262228}
0 commit comments