Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V2 #122

Merged
merged 82 commits into from
May 27, 2020
Merged

V2 #122

Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
5701576
tcp version 1.0
jkralik Nov 9, 2018
15791f7
transform code to pure tcp server
jkralik Nov 26, 2018
83d1004
create RequestMsg
jkralik Dec 1, 2018
d6d18f2
extends request msg
jkralik Dec 4, 2018
28fbcb0
set NonConfirmable as default for client requests
jkralik Apr 20, 2020
3984b62
add test for confirmable message
jkralik Apr 20, 2020
7893a8b
rewrite using messageID
jkralik Apr 20, 2020
c0235b9
Merge branch 'v2' into changeDefaultToNonConfirmable
jkralik Apr 20, 2020
836361e
separate TCP protocol
jkralik Apr 21, 2020
aa61fa4
replace errorCode by error, runable test
jkralik Apr 22, 2020
a15ce6f
impl udp message parser
jkralik Apr 22, 2020
01c5f41
blockwise rewriting
jkralik Apr 24, 2020
ad16a55
blockwise with tests
jkralik Apr 27, 2020
d141f8d
integrate blockwise to udp + implement observe to client
jkralik Apr 28, 2020
fcbc8f6
udp: implement write request
jkralik Apr 28, 2020
5e92370
add PUT, POST, DELETE ops to clientconn
jkralik Apr 28, 2020
6bdd848
fix observation of resources by RFC
jkralik Apr 30, 2020
1c3c917
register get request for observation to get resource content
jkralik Apr 30, 2020
139a7b4
update comments
jkralik May 3, 2020
3ae97b5
examples of usage
jkralik May 3, 2020
06fe12f
implement noreponse
jkralik May 3, 2020
de985b4
Merge branch 'separateProtocols' of github.com:go-ocf/go-coap into se…
jkralik May 3, 2020
b306678
Update options.go
jkralik May 3, 2020
f8a63f6
update comments
jkralik May 3, 2020
80bb6e9
Update options.go
jkralik May 3, 2020
54412ff
update tcp about coap features from udp
jkralik May 4, 2020
d026f11
dlts client+server, add options to all protocols
jkralik May 5, 2020
c5c3ced
provides Context for mux.ClientConn
jkralik May 6, 2020
0ac6d78
update observe example
jkralik May 6, 2020
649e867
fix tests
jkralik May 6, 2020
6f9892a
Merge branch 'master' into v2
jkralik May 6, 2020
7e44012
update README.md
jkralik May 6, 2020
9f6da87
update README.md to newest packages
jkralik May 6, 2020
ea2dfd2
remove debug logs
jkralik May 6, 2020
d1c6824
proper handle udp/dtls confirmable requests + retry
jkralik May 6, 2020
bf660f8
fix tests for windows
jkralik May 7, 2020
080f9c1
merge clients of udp and dtls
jkralik May 7, 2020
7210806
add support for retransmission for writeRequest
jkralik May 7, 2020
474ab7b
renames XYZPayloadXYZ to BodySize and SetBody
jkralik May 7, 2020
3dc2b01
add Client function
jkralik May 7, 2020
1306359
Update README.md
jkralik May 7, 2020
1afd3a6
propagate sequence number over blockwise
jkralik May 8, 2020
959d26f
Merge branch 'v2' of github.com:go-ocf/go-coap into v2
jkralik May 8, 2020
2254d5e
add badget's about backer's and sponsor's
jkralik May 8, 2020
288a064
add description about golang
jkralik May 8, 2020
a5c04b3
add transmission option
jkralik May 8, 2020
bedc77d
link to examples
jkralik May 8, 2020
4c4119f
add new lines
jkralik May 8, 2020
22708b7
Update README.md
jkralik May 10, 2020
a31f765
Update README.md
jkralik May 10, 2020
84c3375
fix DTLS accept loop from exiting
jkralik May 11, 2020
a57b98d
extends Options about Path(), Queries(), ContentFormat()
jkralik May 11, 2020
1280df8
move muxclient as client with common interface for tcp/udp
jkralik May 11, 2020
eddd3e0
add docs for blockwise
jkralik May 12, 2020
a083f59
send reset when observation was not found
jkralik May 12, 2020
0d55403
move conversion function's to pool package
jkralik May 12, 2020
721de6f
fix casting nil value to interface
jkralik May 12, 2020
8cce191
set type Confirmable and MessageID for every client.do
jkralik May 12, 2020
cbe4f1b
fix blockwise for Block1
jkralik May 13, 2020
95d4a93
rename WriteRequest to WriteMessage
jkralik May 13, 2020
9a5754c
fix set option id + stop do function when all was send
jkralik May 13, 2020
1911368
send confirmation message always via udp/writeRequest
jkralik May 13, 2020
97c259b
rename writeRequest to writeMessage
jkralik May 13, 2020
8233f9d
rename mux.ResponseWriter.ClientConn to mux.ResponseWriter.Client
jkralik May 14, 2020
09bfcd2
propagate sequence number to request in mux.Handler
jkralik May 15, 2020
3037f9e
exports Sequence function from client/clientconn
jkralik May 18, 2020
a6e3ed0
add {Set}Observe to message.Options
jkralik May 20, 2020
4843690
add middleware support to router
jkralik May 20, 2020
4396a67
exports NewDeleteRequest for tcp/udp
jkralik May 20, 2020
ccff055
export {Set}Accept for convinience from options
jkralik May 20, 2020
8deb263
fix shutdown of tcp/dtls server
jkralik May 21, 2020
1e541e1
fix WithTLS option for tcp
jkralik May 21, 2020
e13e257
returns valid observe response Code
jkralik May 21, 2020
1fcd6e6
get's underlaying client connection from client
jkralik May 22, 2020
1dc6fb1
test with -race flag
jkralik May 22, 2020
df944db
fix target build
jkralik May 22, 2020
1d4d4f7
clean up after CR
jkralik May 26, 2020
173b031
Merge branch 'master' into v2
jkralik May 26, 2020
7c6854c
clean up 2 for CR
jkralik May 26, 2020
da9edec
clean up 3 for CR
jkralik May 27, 2020
103a8a0
cleanup 3 after CR
jkralik May 27, 2020
84883e5
cleanup server.Serve function
jkralik May 27, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix DTLS accept loop from exiting
  • Loading branch information
jkralik committed May 11, 2020
commit 84c337551b2ae0f96ad86b7d0ca1c5ca776bf628
57 changes: 51 additions & 6 deletions dtls/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func TestClientConn_Get(t *testing.T) {
go func() {
defer wg.Done()
err := s.Serve(l)
t.Log(err)
require.NoError(t, err)
}()

cc, err := dtls.Dial(l.Addr().String(), dtlsCfg)
Expand Down Expand Up @@ -185,7 +185,7 @@ func TestClientConn_Get_SepareateMessage(t *testing.T) {
go func() {
defer wg.Done()
err := s.Serve(l)
t.Log(err)
require.NoError(t, err)
}()

cc, err := dtls.Dial(l.Addr().String(), dtlsCfg, dtls.WithHandlerFunc(func(w *client.ResponseWriter, r *pool.Message) {
Expand Down Expand Up @@ -304,7 +304,7 @@ func TestClientConn_Post(t *testing.T) {
go func() {
defer wg.Done()
err := s.Serve(l)
t.Log(err)
require.NoError(t, err)
}()

cc, err := dtls.Dial(l.Addr().String(), dtlsCfg)
Expand Down Expand Up @@ -431,7 +431,7 @@ func TestClientConn_Put(t *testing.T) {
go func() {
defer wg.Done()
err := s.Serve(l)
t.Log(err)
require.NoError(t, err)
}()

cc, err := dtls.Dial(l.Addr().String(), dtlsCfg)
Expand Down Expand Up @@ -535,7 +535,7 @@ func TestClientConn_Delete(t *testing.T) {
go func() {
defer wg.Done()
err := s.Serve(l)
t.Log(err)
require.NoError(t, err)
}()

cc, err := dtls.Dial(l.Addr().String(), dtlsCfg)
Expand Down Expand Up @@ -587,7 +587,8 @@ func TestClientConn_Ping(t *testing.T) {
wg.Add(1)
go func() {
defer wg.Done()
s.Serve(l)
err := s.Serve(l)
require.NoError(t, err)
}()

cc, err := dtls.Dial(l.Addr().String(), dtlsCfg)
Expand All @@ -604,3 +605,47 @@ func TestClientConn_Ping(t *testing.T) {
err = cc.Ping(ctx)
require.NoError(t, err)
}

func TestClientConn_HandeShakeFailure(t *testing.T) {
dtlsCfg := &piondtls.Config{
PSK: func(hint []byte) ([]byte, error) {
fmt.Printf("Hint: %s \n", hint)
return []byte{0xAB, 0xC1, 0x23}, nil
},
PSKIdentityHint: []byte("Pion DTLS Server"),
CipherSuites: []piondtls.CipherSuiteID{piondtls.TLS_PSK_WITH_AES_128_CCM_8},
ConnectContextMaker: func() (context.Context, func()) {
return context.WithTimeout(context.Background(), 1*time.Second)
},
}
l, err := coapNet.NewDTLSListener("udp", "", dtlsCfg)
require.NoError(t, err)
defer l.Close()
var wg sync.WaitGroup
defer wg.Wait()

s := dtls.NewServer()
defer s.Stop()

wg.Add(1)
go func() {
defer wg.Done()
err := s.Serve(l)
require.NoError(t, err)
}()

dtlsCfgClient := &piondtls.Config{
PSK: func(hint []byte) ([]byte, error) {
fmt.Printf("Hint: %s \n", hint)
return []byte{0xAB, 0xC1, 0x24}, nil
},
PSKIdentityHint: []byte("Pion DTLS Client"),
CipherSuites: []piondtls.CipherSuiteID{piondtls.TLS_PSK_WITH_AES_128_CCM_8},
ConnectContextMaker: func() (context.Context, func()) {
return context.WithTimeout(context.Background(), 1*time.Second)
},
}
_, err = dtls.Dial(l.Addr().String(), dtlsCfgClient)
require.Error(t, err)
//time.Sleep(time.Second)
}
118 changes: 59 additions & 59 deletions dtls/example_test.go
Original file line number Diff line number Diff line change
@@ -1,59 +1,59 @@
package dtls_test
import (
"context"
"fmt"
"io/ioutil"
"log"
"time"
"github.com/go-ocf/go-coap/v2/dtls"
"github.com/go-ocf/go-coap/v2/net"
piondtls "github.com/pion/dtls/v2"
)
func ExampleGet() {
dtlsCfg := &piondtls.Config{
PSK: func(hint []byte) ([]byte, error) {
fmt.Printf("Hint: %s \n", hint)
return []byte{0xAB, 0xC1, 0x23}, nil
},
PSKIdentityHint: []byte("Pion DTLS Server"),
CipherSuites: []piondtls.CipherSuiteID{piondtls.TLS_PSK_WITH_AES_128_CCM_8},
}
conn, err := dtls.Dial("pluggedin.cloud:5684", dtlsCfg)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
res, err := conn.Get(ctx, "/oic/res")
if err != nil {
log.Fatal(err)
}
data, err := ioutil.ReadAll(res.Body())
if err != nil {
log.Fatal(err)
}
fmt.Printf("%v", data)
}
func ExampleServe() {
dtlsCfg := &piondtls.Config{
PSK: func(hint []byte) ([]byte, error) {
fmt.Printf("Hint: %s \n", hint)
return []byte{0xAB, 0xC1, 0x23}, nil
},
PSKIdentityHint: []byte("Pion DTLS Server"),
CipherSuites: []piondtls.CipherSuiteID{piondtls.TLS_PSK_WITH_AES_128_CCM_8},
}
l, err := net.NewDTLSListener("udp", "0.0.0.0:5683", dtlsCfg)
if err != nil {
log.Fatal(err)
}
defer l.Close()
s := dtls.NewServer()
defer s.Stop()
log.Fatal(s.Serve(l))
}
package dtls_test

import (
"context"
"fmt"
"io/ioutil"
"log"
"time"

"github.com/go-ocf/go-coap/v2/dtls"
"github.com/go-ocf/go-coap/v2/net"
piondtls "github.com/pion/dtls/v2"
)

func ExampleGet() {
dtlsCfg := &piondtls.Config{
PSK: func(hint []byte) ([]byte, error) {
fmt.Printf("Hint: %s \n", hint)
return []byte{0xAB, 0xC1, 0x23}, nil
},
PSKIdentityHint: []byte("Pion DTLS Server"),
CipherSuites: []piondtls.CipherSuiteID{piondtls.TLS_PSK_WITH_AES_128_CCM_8},
}
conn, err := dtls.Dial("pluggedin.cloud:5684", dtlsCfg)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
res, err := conn.Get(ctx, "/oic/res")
if err != nil {
log.Fatal(err)
}
data, err := ioutil.ReadAll(res.Body())
if err != nil {
log.Fatal(err)
}
fmt.Printf("%v", data)
}

func ExampleServe() {
dtlsCfg := &piondtls.Config{
PSK: func(hint []byte) ([]byte, error) {
fmt.Printf("Hint: %s \n", hint)
return []byte{0xAB, 0xC1, 0x23}, nil
},
PSKIdentityHint: []byte("Pion DTLS Server"),
CipherSuites: []piondtls.CipherSuiteID{piondtls.TLS_PSK_WITH_AES_128_CCM_8},
}
l, err := net.NewDTLSListener("udp", "0.0.0.0:5683", dtlsCfg)
if err != nil {
log.Fatal(err)
}
defer l.Close()
s := dtls.NewServer()
defer s.Stop()
log.Fatal(s.Serve(l))
}
8 changes: 7 additions & 1 deletion dtls/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,14 @@ func (s *Server) Serve(l Listener) error {
if err != nil {
switch err {
case context.DeadlineExceeded, context.Canceled:
select {
case <-s.ctx.Done():
default:
s.errors(fmt.Errorf("cannot accept connection: %w", err))
continue
}
wg.Wait()
return fmt.Errorf("cannot accept: %w", err)
return nil
default:
continue
}
Expand Down
5 changes: 4 additions & 1 deletion examples/mcast/client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ func main() {
s := udp.NewServer()
defer s.Stop()
go func() {
s.Serve(l)
err := s.Serve(l)
if err != nil {
log.Println(err)
}
}()

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/dsnet/golib/memfile v0.0.0-20190531212259-571cdbcff553 h1:qd7Hp/zOU5vOHkyfqefAFop3O4ATL3F8vxrYmL2q8bI=
github.com/dsnet/golib/memfile v0.0.0-20190531212259-571cdbcff553/go.mod h1:tXGNW9q3RwvWt1VV2qrRKlSSz0npnh12yftCSCy2T64=
github.com/go-ocf/go-coap v0.0.0-20200503182930-509338af26c8 h1:ieuAqWZcqrEAowslHtq7VhF3iQVaw3wx0NrAKzOj2dc=
github.com/go-ocf/go-coap v0.0.0-20200507195925-de47755e89b8 h1:8OFS9Z/RAvTnH72LdeRZK1TGTuQ+xcf9rajHoYXlxnk=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pion/dtls/v2 v2.0.1-0.20200503085337-8e86b3a7d585 h1:0v1k/bHrth28TctdEWnrCgLehYn3nOvFAwOwtwmyC34=
Expand Down
8 changes: 4 additions & 4 deletions message/codes/codes.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ var strToCode = map[string]Code{
`"GatewayTimeout"`: GatewayTimeout,
`"ProxyingNotSupported"`: ProxyingNotSupported,
`"Capabilities and Settings Messages"`: CSM,
`"Ping"`: Ping,
`"Pong"`: Pong,
`"Release"`: Release,
`"Abort"`: Abort,
`"Ping"`: Ping,
`"Pong"`: Pong,
`"Release"`: Release,
`"Abort"`: Abort,
}

// UnmarshalJSON unmarshals b into the Code.
Expand Down
40 changes: 20 additions & 20 deletions message/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,26 +139,26 @@ type OptionDef struct {
}

var CoapOptionDefs = map[OptionID]OptionDef{
IfMatch: OptionDef{ValueFormat: ValueOpaque, MinLen: 0, MaxLen: 8},
URIHost: OptionDef{ValueFormat: ValueString, MinLen: 1, MaxLen: 255},
ETag: OptionDef{ValueFormat: ValueOpaque, MinLen: 1, MaxLen: 8},
IfNoneMatch: OptionDef{ValueFormat: ValueEmpty, MinLen: 0, MaxLen: 0},
Observe: OptionDef{ValueFormat: ValueUint, MinLen: 0, MaxLen: 3},
URIPort: OptionDef{ValueFormat: ValueUint, MinLen: 0, MaxLen: 2},
LocationPath: OptionDef{ValueFormat: ValueString, MinLen: 0, MaxLen: 255},
URIPath: OptionDef{ValueFormat: ValueString, MinLen: 0, MaxLen: 255},
ContentFormat: OptionDef{ValueFormat: ValueUint, MinLen: 0, MaxLen: 2},
MaxAge: OptionDef{ValueFormat: ValueUint, MinLen: 0, MaxLen: 4},
URIQuery: OptionDef{ValueFormat: ValueString, MinLen: 0, MaxLen: 255},
Accept: OptionDef{ValueFormat: ValueUint, MinLen: 0, MaxLen: 2},
LocationQuery: OptionDef{ValueFormat: ValueString, MinLen: 0, MaxLen: 255},
Block2: OptionDef{ValueFormat: ValueUint, MinLen: 0, MaxLen: 3},
Block1: OptionDef{ValueFormat: ValueUint, MinLen: 0, MaxLen: 3},
Size2: OptionDef{ValueFormat: ValueUint, MinLen: 0, MaxLen: 4},
ProxyURI: OptionDef{ValueFormat: ValueString, MinLen: 1, MaxLen: 1034},
ProxyScheme: OptionDef{ValueFormat: ValueString, MinLen: 1, MaxLen: 255},
Size1: OptionDef{ValueFormat: ValueUint, MinLen: 0, MaxLen: 4},
NoResponse: OptionDef{ValueFormat: ValueUint, MinLen: 0, MaxLen: 1},
IfMatch: {ValueFormat: ValueOpaque, MinLen: 0, MaxLen: 8},
URIHost: {ValueFormat: ValueString, MinLen: 1, MaxLen: 255},
ETag: {ValueFormat: ValueOpaque, MinLen: 1, MaxLen: 8},
IfNoneMatch: {ValueFormat: ValueEmpty, MinLen: 0, MaxLen: 0},
Observe: {ValueFormat: ValueUint, MinLen: 0, MaxLen: 3},
URIPort: {ValueFormat: ValueUint, MinLen: 0, MaxLen: 2},
LocationPath: {ValueFormat: ValueString, MinLen: 0, MaxLen: 255},
URIPath: {ValueFormat: ValueString, MinLen: 0, MaxLen: 255},
ContentFormat: {ValueFormat: ValueUint, MinLen: 0, MaxLen: 2},
MaxAge: {ValueFormat: ValueUint, MinLen: 0, MaxLen: 4},
URIQuery: {ValueFormat: ValueString, MinLen: 0, MaxLen: 255},
Accept: {ValueFormat: ValueUint, MinLen: 0, MaxLen: 2},
LocationQuery: {ValueFormat: ValueString, MinLen: 0, MaxLen: 255},
Block2: {ValueFormat: ValueUint, MinLen: 0, MaxLen: 3},
Block1: {ValueFormat: ValueUint, MinLen: 0, MaxLen: 3},
Size2: {ValueFormat: ValueUint, MinLen: 0, MaxLen: 4},
ProxyURI: {ValueFormat: ValueString, MinLen: 1, MaxLen: 1034},
ProxyScheme: {ValueFormat: ValueString, MinLen: 1, MaxLen: 255},
Size1: {ValueFormat: ValueUint, MinLen: 0, MaxLen: 4},
NoResponse: {ValueFormat: ValueUint, MinLen: 0, MaxLen: 1},
}

// MediaType specifies the content format of a message.
Expand Down
2 changes: 1 addition & 1 deletion message/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func TestAddBytesOption(t *testing.T) {
n, err := options.GetBytess(0, v)
require.Equal(t, nil, err)
require.Equal(t, 2, n)
require.Equal(t, [][]byte{[]byte{0x30}, []byte{0x31}}, v)
require.Equal(t, [][]byte{{0x30}, {0x31}}, v)
}

func testRemoveBytesOption(t *testing.T, options Options, option OptionID, expectedLen int) Options {
Expand Down
7 changes: 2 additions & 5 deletions net/dtlslistener.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ func (l *DTLSListener) acceptLoop() {
conn, err := l.listener.Accept()
select {
case l.connCh <- connData{conn: conn, err: err}:
if err != nil {
return
}
case <-l.doneCh:
return
}
Expand Down Expand Up @@ -98,14 +95,14 @@ func (l *DTLSListener) AcceptWithContext(ctx context.Context) (net.Conn, error)
}
err := l.SetDeadline(time.Now().Add(l.heartBeat))
if err != nil {
return nil, fmt.Errorf("cannot accept connections: %v", err)
return nil, fmt.Errorf("cannot set deadline to accept connection: %v", err)
}
rw, err := l.Accept()
if err != nil {
if isTemporary(err) {
continue
jkralik marked this conversation as resolved.
Show resolved Hide resolved
}
return nil, fmt.Errorf("cannot accept connections: %v", err)
return nil, fmt.Errorf("cannot accept connection: %v", err)
}
return rw, nil
}
Expand Down
4 changes: 2 additions & 2 deletions net/tcplistener.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,14 @@ func (l *TCPListener) AcceptWithContext(ctx context.Context) (net.Conn, error) {
}
err := l.SetDeadline(time.Now().Add(l.heartBeat))
if err != nil {
return nil, fmt.Errorf("cannot accept connections: %v", err)
return nil, fmt.Errorf("cannot set deadline to accept connection: %v", err)
}
rw, err := l.listener.Accept()
if err != nil {
if isTemporary(err) {
continue
}
return nil, fmt.Errorf("cannot accept connections: %v", err)
return nil, fmt.Errorf("cannot accept connection: %v", err)
}
return rw, nil
}
Expand Down
4 changes: 2 additions & 2 deletions net/tlslistener.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ func (l *TLSListener) AcceptWithContext(ctx context.Context) (net.Conn, error) {
}
err := l.SetDeadline(time.Now().Add(l.heartBeat))
if err != nil {
return nil, fmt.Errorf("cannot accept connections: %v", err)
return nil, fmt.Errorf("cannot set deadline to accept connection: %v", err)
}
rw, err := l.listener.Accept()
if err != nil {
if isTemporary(err) {
continue
}
return nil, fmt.Errorf("cannot accept connections: %v", err)
return nil, fmt.Errorf("cannot accept connection: %v", err)
}
return rw, nil
}
Expand Down
Loading