55 "io"
66 "net"
77 "sync"
8+ "sync/atomic"
89 "time"
910)
1011
@@ -33,15 +34,15 @@ type Listener struct {
3334// return the address of the client instead of the proxy address. Each connection
3435// will have its own readHeaderTimeout and readDeadline set by the Accept() call.
3536type Conn struct {
36- bufReader * bufio.Reader
37+ readDeadline atomic.Value // time.Time
38+ once sync.Once
39+ readErr error
3740 conn net.Conn
41+ Validate Validator
42+ bufReader * bufio.Reader
3843 header * Header
39- once sync.Once
4044 ProxyHeaderPolicy Policy
41- Validate Validator
42- readErr error
4345 readHeaderTimeout time.Duration
44- readDeadline time.Time
4546}
4647
4748// Validator receives a header and decides whether it is a valid one
@@ -215,7 +216,7 @@ func (p *Conn) UDPConn() (conn *net.UDPConn, ok bool) {
215216
216217// SetDeadline wraps original conn.SetDeadline
217218func (p * Conn ) SetDeadline (t time.Time ) error {
218- p .readDeadline = t
219+ p .readDeadline . Store ( t )
219220 return p .conn .SetDeadline (t )
220221}
221222
@@ -224,7 +225,7 @@ func (p *Conn) SetReadDeadline(t time.Time) error {
224225 // Set a local var that tells us the desired deadline. This is
225226 // needed in order to reset the read deadline to the one that is
226227 // desired by the user, rather than an empty deadline.
227- p .readDeadline = t
228+ p .readDeadline . Store ( t )
228229 return p .conn .SetReadDeadline (t )
229230}
230231
@@ -250,7 +251,11 @@ func (p *Conn) readHeader() error {
250251 // Therefore, we check whether the error is a net.Timeout and if it is, we decide
251252 // the proxy proto does not exist and set the error accordingly.
252253 if p .readHeaderTimeout > 0 {
253- p .conn .SetReadDeadline (p .readDeadline )
254+ t := p .readDeadline .Load ()
255+ if t == nil {
256+ t = time.Time {}
257+ }
258+ p .conn .SetReadDeadline (t .(time.Time ))
254259 if netErr , ok := err .(net.Error ); ok && netErr .Timeout () {
255260 err = ErrNoProxyProtocol
256261 }
0 commit comments