Giter VIP home page Giter VIP logo

go-coap's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-coap's Issues

connect to coap server with specific source port

I would like to know if there is a way to create a new client, by specifying a specific UDP source port like how we do with the net package.

        server, _ := net.ResolveUDPAddr("udp", "google.com:80")
        client, _ := net.ResolveUDPAddr("udp", ":50000")
        conn, err := net.DialUDP("tcp", client, server)

Right now, the API does not seem to provide a way to specify the UDP port to send requests.

Support for DTLS certificate export

I couldn't find this to be supported ATM, but how difficult would it be to support this or is this already supported?

I'm also still figuring out in pion/dtls how i can export certificates, so once that is figured out, this ticket should become more specific. Nonetheless, I figured creating a ticket here to see if anyone has done anything similar, and get the ball rolling once I've figured out how to export the certificate from pion/dtls.
After a fist look (and I'm not sure whether this is indeed right until the dtls is figured out) it might mean that the dtls.Conn needs to be exposed somehow from coap.ListenAndServeDTLS.

Handle blockwise observation responses

Current implementation server creates only first block of blockwise and send it to observer and in observer its trigger GET but it doesn't use payload of firstblock:

server: Add support handling for GET with Block2
client: Use payload from notification, and send request with Block2

IoTivity for GET request with Block2 returns response with code GET:
https://jira.iotivity.org/browse/IOT-3209

DTLS peer certificates

I noted that in v2.0.2 I can't get the peer certificates any more, which were added in #115. Am I just looking in the wrong place (responseWriter.Client()) or was that code removed somewhere in v2.0.1 ?

not enough arguments in call to l.listener.Close

Hi , when i try to install this package it gives me the following error:

github.com/go-ocf/go-coap/net

../../go/src/github.com/go-ocf/go-coap/net/dtlslistener.go:126:25: not enough arguments in call to l.listener.Close
have ()
want (time.Duration)

I have already installed this package many times and today this is happening.

Help me please it's urgent !
Go version 1.12.9

Thank you.

middleware.go comment bug mentions HTTP

middleware.go in v2 has a comment:

// MiddlewareFunc is a function which receives an http.Handler and returns another http.Handler.
// Typically, the returned handler is a closure which does something with the http.ResponseWriter and http.Request passed
// to it, and then calls the handler passed as parameter to the MiddlewareFunc.

I believe that it is a copy-paste error since it looks exactly like the comment in gorilla mux.

Is that correct? It'll be super-easy to fix.

ResponseWriter has unexported functions and con not be implemented outside

The ResponseWriter can not be implemented outside the go-coap packahe due to private fields.

I like to implement a ResponseRecorder inside my coaptest package. Similiar to the httptest package.

Moving the private fields into a separate private interface would probably be sufficient.

If you are interested, I would also offer to provide a pull request (after checking how much effort is is ;) )

blockwise observe

We are trying to observe a resource with blockwise enabled on UDP, but we receive only the first block. The client doesn't send the second request with block option 2 . We simply create a request with client.ObserveWithContext.... Are we missing something?

Register mcast serve and request mcast UDP and UDP at the same time, unable to resolve ordinary UDP URI

We registered mcast server and set URI of interest. But after business logic receives the first mcast, it receives ordinary UDP packets. However, ordinary UDP package URIs have been unable to parse successfully, resulting in the inability to handle to the corresponding method. Find out the reason: We started mcast service, ordinary UDP request on the server selected UDP path, resulting in our registered URI Map in UDP package parsing URI MAP is empty, so can not match URI and Handle Method. The server of mcast chooses the URI-MAP of mcast, which can have our registered URI, and can match to URI and method normally.

To solve this problem, you need to merge serves locally or queue read consumption when listening. Or is there any other way of using it to support us in the business of mcast UDP and UDP at the same time?

z:map[.well-known/core:{0x17e0f4 .well-known/core} .sys/sessMngr:{0x17e500 .sys/sessMngr}]E
and 
z:map[]E

handleBlockWiseMsg 4 : <nil>  
handleBlockWiseMsg r.msg=&{{0 2 5056 [147 174] [123 34 116 121 112 101 34 58 49 44 34 109 111 100 101 83 117 112 112 111 114 116 34 58 49 44 34 115 110 49 34 58 34 52 53 52 49 52 49 55 51 54 56 52 54 54 97 52 99 34 44 34 115 101 113 34 58 50 54 50 54 52 125] [{11 .sys} {11 sessMngr}]}}
handleBlockWiseMsg CON 
handleBlockWiseMsg 1 : <nil>  
handleBlockWiseMsg 2 : <nil>  
handleBlockWiseMsg 3 : (func(coap.ResponseWriter, *coap.Request))(0x17bf80)  
z:map[]E
update:E
match:E
match default : 
handleBlockWiseMsg 4 : <nil>  
handleBlockWiseMsg r.msg=&{{1 1 5057 [59 224] [] [{11 .well-known} {11 core} {15 st=homeCenter}]}}
z:map[.well-known/core:{0x17e0f4 .well-known/core} .sys/sessMngr:{0x17e500 .sys/sessMngr}]E
match:.well-known/coreE
2019/01/04 23:08:01 Got message in handleMcast: path=[".well-known" "core"]: &coap.DgramMessage{MessageBase:coap.MessageBase{typ:0x1, code:0x1, messageID:0x13c1, token:[]uint8{0x3b, 0xe0}, payload:[]uint8{}, opts:coap.options{coap.option{ID:0xb, Value:".well-known"}, coap.option{ID:0xb, Value:"core"}, coap.option{ID:0xf, Value:"st=homeCenter"}}}} from 192.168.2.20:5683

Panic using RSA keys with CoAP DTLS listener

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x38 pc=0x612897]

goroutine 35 [running]:
gitlab.com/hjames9/coapter/vendor/github.com/pion/dtls.(*Conn).Read(0x0, 0xc000164000, 0x2000, 0x2000, 0x0, 0x0, 0x0)
	/home/hjames/.gvm/pkgsets/go1.13.3/global/src/gitlab.com/hjames9/coapter/vendor/github.com/pion/dtls/conn.go:253 +0x37
gitlab.com/hjames9/coapter/vendor/github.com/go-ocf/go-coap/net.(*ConnDTLS).readLoop(0xc00015c000)
	/home/hjames/.gvm/pkgsets/go1.13.3/global/src/gitlab.com/hjames9/coapter/vendor/github.com/go-ocf/go-coap/net/connDTLS.go:29 +0xdb
created by gitlab.com/hjames9/coapter/vendor/github.com/go-ocf/go-coap/net.NewConnDTLS
	/home/hjames/.gvm/pkgsets/go1.13.3/global/src/gitlab.com/hjames9/coapter/vendor/github.com/go-ocf/go-coap/net/connDTLS.go:52 +0xff

Loaded CoAP in DTLS mode with RSA keys

keys, err := tls.LoadX509KeyPair("certs/coapter_cert_rsa_2048.pem", "certs/coapter_key_rsa_2048.pem")
if err != nil {
	log.Fatal().Err(err).Send()
	return
}
certificate, err := x509.ParseCertificate(keys.Certificate[0])
if err != nil {
	log.Fatal().Err(err).Send()
	return
}
privateKey := keys.PrivateKey

config := &dtls.Config{
	Certificate:           certificate,
	PrivateKey:            privateKey,
	ExtendedMasterSecret:  dtls.RequireExtendedMasterSecret,
	ConnectTimeout:        dtls.ConnectTimeoutOption(30 * time.Second),
	InsecureSkipVerify:    true,
	VerifyPeerCertificate: certVerify,
	ClientAuth:            dtls.RequireAnyClientCert,
}
...
mux := coap.NewServeMux()
err = mux.Handle("/test", coap.HandlerFunc(handleCoapTest))
if err != nil {
	log.Fatal().Err(err).Send()
	return
}

err = coap.ListenAndServeDTLS("udp-dtls", ":5688", config, mux)
if err != nil {
	log.Error().Err(err).Send()
}

When the listener receives a DTLS message on the wire, it panics due to the DTLS connection object not being initialized properly due to setting up with RSA certs. This should fail more gracefully in the ListenAndServerDTLS function instead of the panic.

It's correctly handled by DialDTLS() function where I receive "dtls: invalid private key type" error message.
The reason for that is that DialDTLS() creates the DTLS connection object via pion/dtls.Dial(), which eventually calls a function called createConn that has the key type check:
https://github.com/pion/dtls/blob/master/conn.go#L101

The listener code however, directly creates a dtls.Server object
https://github.com/go-ocf/go-coap/blob/92481866bd1713e2c98a02933f472c0f8a28a91c/server.go#L105
This bypasses all the sanity checks that exist in the pion/dtls library creating the server DTLS server connection object
https://github.com/pion/dtls/blob/master/conn.go#L240

Do you agree with this assessment? I can help submit a PR to change this behaviour if you think this is the correct approach.

Thanks!

Shutdown waits for end of processing

Hello,

Thank you very much for the excellent project! So far this is the best CoAP library that I have used!

I am using it for an application that I am creating and I started looking into the shutdown logic. From what I saw in the code, when the shutdown method is called, the listener stops accepting requests, but there is no guarantee that all the requests that are already accepted will finish their processing. I believe I can add logic in my handler type for keeping track of this, so that my application can call server.Shutdown() followed by handler.Close() and have a guarantee that all processing is over, but I thought the better approach might be if the server library takes care of it as other will face a similar problem.

I need to make sure all the processing is over as I don't want to exit the application and interrupt some processing that might result in inconsistent state.

Cheers,

client can not recreate connection with coap server

i can not find how to release ClientConn in server's conns.when client down, the server can not write response to client than it use cancle function but the ClientConn still in server's conns. The next time, client recreate connection with the server, the server do not create ClientConn but get it from server's conns,it cause ClientConn's context is cancle

FR: Middleware example

V2 introduced middlewares to mux. It would be helpful to add an example showing how to implement a middleware handler.

Dependency on pion/dtls/v2 issue

Hi everyone,

I am running into a problem setting up this project. Hopefully someone can shed some light...

Setup and environment

I am trying to download this project with:
$ go get github.com/go-ocf/go-coap

The error from the go get cmd:
$ src/github.com/go-ocf/go-coap/net/dtlslistener.go:21:13: undefined: dtls.Listener

My go version on ubuntu 16:
$ go version
$ go version go1.11.1 linux/amd64

Investigation

I see that all pion/dtls paths point to a v2 directory, however I can't find a v2 directory in any of the source, so its not surprising dtls.Listener is undefined. The go.sum file calls out the tag v2.0.0-rc.5 for pion/dtls, but that tag definitely does not have a v2 directory.

Also, I see pion/dtls devs discuss using the v2 directory here, but ultimately deciding against it ?
v2 tracking issue on pion/dtls

Update

I have discovered go modules, which I needed to enable.

This command successfully downloaded the dependencies:
$ cd $GOPATH/src/github.com/go-ocf/go-coap
$ GO111MODULE=on go get -t -v ./ ...

Update 2

Previous command did not fix original problem as expected, but it did download more of the dependencies. I am still encountering the dtls.Listener undefined error.

Final Update

go1-13 is required.


Any help here would be much appreciated. Thanks!

close inactive udp session

in current implementation udp session is hold forever. It's need to define and implement timeout which cause close udp session.

Connection from client not reestablished when server restarts using DTLS

Using server from this example:
https://github.com/go-ocf/go-coap/blob/master/examples/dtls/server/main.go
i.e. "go run main.go"

And slightly modified client to continuously call coap.Get() every 3 seconds to send/receive data
https://github.com/go-ocf/go-coap/blob/master/examples/dtls/client/main.go

    co, err := coap.DialDTLS("udp", "localhost:5688", &dtls.Config{
        PSK: func(hint []byte) ([]byte, error) {
            fmt.Printf("Server's hint: %s \n", hint)
            return []byte{0xAB, 0xC1, 0x23}, nil 
        },
        PSKIdentityHint: []byte("Pion DTLS Server"),
        CipherSuites:    []dtls.CipherSuiteID{dtls.TLS_PSK_WITH_AES_128_CCM_8},
    })  
    if err != nil {
        log.Fatalf("Error dialing: %v", err)
    }   
    for {
        path := "/a"
        if len(os.Args) > 1 { 
            path = os.Args[1]
        }
        resp, err := co.Get(path)
        if err != nil {
            log.Fatalf("Error sending request: %v", err)
        }

        log.Printf("Response payload: %v", resp.Payload())
        time.Sleep(3 * time.Second)
    }

If I restart the server process, the client never recovers and detects that the Get() fails. Get() blocks indefinitely and you're never able to determine that the connection fails and attempt to reestablish it via Dial(). I'm unsure if I'm missing something, but what's the best practice to follow in this scenario?

Implement MaxConns and MaxConnsPerHost to server

MaxConnsPerHost optionally limits the total number of connections per host served by server(client).

MaxConns optionally limits the total number of connections served by server(client).

Zero means no limit.

Custom options

Thanks for a great piece of software!
I’ve started using this library to communicate with an IoT device but I ran in to an issue. The device uses some non-standard options to convey certain pieces of information, but this library seems to simply omit any options that aren’t among the ones hardcoded. Looking at the code there doesn’t seem to be any chance of catching those custom options. Is there a reason it’s designed this way?

Move Server out from Connection to Client

For transparent control over Server's lifetime, its lifetime should be managed by the Client instead of the Connection.

When MulticastClientConn is closed, it shuts the Server down even for the connections of responses to PublishMsgWithContext. These connections are kept open for extended periods for further communication.

updating to the commit hash (6ad5eb4) causes error

Updating to the hash-6ad5eb4 of the library causes the following error when trying to run a go file using the library.

# github.com/go-ocf/go-coap/net
../../../../../../go/pkg/mod/github.com/go-ocf/[email protected]/net/dtlslistener.go:21:13: undefined: dtls.Listener

It looks like the latest release candidate of the dependency pion/[email protected] seems to be causing this issue.

However, when I revert back to an older version of the library which points to this version pion/[email protected], the issue is resolved.

runtime error with empty path resource

I can't request an empty resource (co.Get("")or co.Get("/")) which I believe should be possible according to the rfc. Other clients and public test servers such as coap.me and californium.eclipse.org do respond to these requests.

Here's the stack trace:

panic: runtime error: index out of range

goroutine 1 [running]:
github.com/go-ocf/go-coap.(*MessageBase).SetPathString(0xc00014a000, 0x121f26a, 0x1)
	/Users/gh0st42/go/pkg/mod/github.com/go-ocf/[email protected]/message.go:594 +0xac
github.com/go-ocf/go-coap.(*ClientCommander).newGetDeleteRequest(0xc0000108c0, 0x121f26a, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0)
	/Users/gh0st42/go/pkg/mod/github.com/go-ocf/[email protected]/clientcommander.go:33 +0x15b
github.com/go-ocf/go-coap.(*ClientCommander).NewGetRequest(0xc0000108c0, 0x121f26a, 0x1, 0x0, 0x0, 0x0, 0x0)
	/Users/gh0st42/go/pkg/mod/github.com/go-ocf/[email protected]/clientcommander.go:60 +0x44
github.com/go-ocf/go-coap.(*ClientCommander).Get(0xc0000108c0, 0x121f26a, 0x1, 0xc00008cae0, 0x0, 0x0, 0xc000082180)
	/Users/gh0st42/go/pkg/mod/github.com/go-ocf/[email protected]/clientcommander.go:116 +0x43
github.com/go-ocf/go-coap.(*ClientConn).Get(0xc00008cae0, 0x121f26a, 0x1, 0xc, 0xc00008cae0, 0x0, 0x0)
	/Users/gh0st42/go/pkg/mod/github.com/go-ocf/[email protected]/client.go:311 +0x7c
main.main()
	/Users/gh0st42/Code/go/copperminer/cmds/coap.go:21 +0xe9
exit status 2

RFC7967 Implementation

RFC7967, a new coap option called No-Response would be useful to tell the server explicitly to suppress the responses for any particular request from the server.

Option to disable keep-alive feature

Is it currently possible to disable the keep-alive feature (added in #93)? If so I weren't able to find it.

I'm communicating with an embedded device which doesn't have any keep-alive functionality implemented so gets confused with those message, especially when they're coming in between regular messages.

If not possible I'd very much like some configuration to be able to disable this feature, would that be possible? Also, where does this feature come from? I couldn't find anything of it in the RFC 7252.

Message Type Confirmable instead of Acknowledge during Block-wise transfer

CoAP server (examples/simple/server/main.go) on payload bearing POST request using block-wise transfer is responding with Message Type Confirmable instead of Acknowledge. Example of transfer follows.

Sending to server:
Confirmable POST Request, Options: Block[1:0/1/128] and Size[1:300]

0000   48 02 b3 44 35 cb d3 f8 5f a4 64 76 d1 0e 0b d2
0010   14 01 2c ff 61 61 61 61 61 61 61 61 61 61 61 61
0020   61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
0030   61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
0040   61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
0050   61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
0060   61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
0070   61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
0080   61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
0090   61 61 61 61

Response from server:
Type - Confirmable, Code[2.31], Options: Block[1:0/1/128]
0000 48 5f b3 44 35 cb d3 f8 5f a4 64 76 d1 0e 0b

Optional blockwise transfer for udp

When we connect to a node with UDP via DialWithContext, blockwise transfer is automatically enabled.
I have not seen an easy option to disable the block wise transfer, but would need it as the other device does not support blockwise transfer.

Could you imagine adding that as an argument?
Or is it already somehow possible?

[Observable] Set CON/NON for notifications

RFC7641 states:

A notification can be confirmable or non-confirmable, i.e., it can be
sent in a confirmable or a non-confirmable message. The message type
used for a notification is independent of the type used for the
request and of any previous notification.

The ResponseWriter and Message interfaces are both missing an option to set the type of a message to CON/NON.

Is there a way to set message type for a notification when responding to a observe request?

DTLS - multiple handshake at the same time

Testing the coaps feature

go run examples/dtls/server/main.go

it seems, that the server is only able to handle one DTLS handshake after the other.
Is that the intended behavior?

modifying messge within middleware

hey, i am wondering how i could implement a middleware like "json-body to object" ..
parse it, convert it and EXTEND the message for later use cases. :)

is this actually possible? how?

if not, is this planed?

thanks!

Certificate validation in pion/dtls

This is not a bug, but a heads-up. We've just merged a change to enable certificate validation, as well as being able to provide your own Root CA pool etc, much like crypto/tls does: pion/dtls#81. It'll go out once we tag v1.5.0.

Nothing changes for go-coap, it's just that there's now some additional fields in dtls.Config that can be set to control this behaviour. I don't think any of it needs to be set by default but it might be good to review it real quick in case it might cause problems.

WriteMsg

Dear go-coap developers,
I am trying to use WriteMsg, with a timeout.
I set DialTimeout, WriteTimeout, ReadTimeout on client
and the message is POST & NonConfirmable.
I need the WriteMsg not to block forever when the unit is off the mesh (Powered down).
But it still hangs with these settings. I suspect I have missed a setting, but cannot
see what. It would be useful if one of the examples included setting timeouts.
Thank you for your time.

Example Block-wise Transfer

Would it be possible to add an example of the use of Block-wise Transfer to the examples.
I am trying to transfer a binary file to an end-device, and am trying to make use of
this feature.

HTTP <> CoAP support via RFC 8075

RFC 8075 provides guidelines for creating a cross-proxy, allowing HTTP endpoints to communicate with CoAP servers. That's very convenient for mobile clients and especially useful for web clients that can only make HTTP or WS requests.

Is there any plans or interest to support RFC 8075, either in go-coap or as a separate repo?

go get fails

go get github.com/go-ocf/go-coap
../../../go/src/github.com/go-ocf/go-coap/message/message.go:8:2: code in directory /home/sascha/go/src/github.com/go-ocf/go-coap/message/codes expects import "github.com/go-ocf/go-coap/codes"

Why skip unrecognized options?

As described in the documentation RFC7252:

The IANA policy for future additions to this sub-registry is split
into three tiers as follows. The range of 0..255 is reserved for
options defined by the IETF (IETF Review or IESG Approval). The
range of 256..2047 is reserved for commonly used options with public
specifications (Specification Required). The range of 2048..64999 is
for all other options including private or vendor-specific ones,
which undergo a Designated Expert review to help ensure that the
option semantics are defined correctly. The option numbers between
65000 and 65535 inclusive are reserved for experiments. They are not
meant for vendor-specific use of any kind and MUST NOT be used in
operational deployments.

We can define options in range of 2048..64999 for private use. So is there any way we can edit optionDefs for private options?

Combined Client and Server possible?

It is possible to have a connection where both sides can initiate a request? I'm wanting to use this library to handle LWM2M bootstrapping which needs requests in both directions, but I didn't see a way to do this.

Example LWM2M bootstrap flow:

image

Client connection method APIs should allow setting of CoAP options

@jkralik Since the Message object isn't exposed on the method APIs e.g. GetWithContext, PostWithContext, PutWithContext, etc. there's currently no way to use those APIs and set any of the CoAP options such as URIQuery, ETag, etc.

In addition, if you attempt to build a confirmable Message directly and use WriteMsgWithContext, it seems to have strange behavior of the server and client constantly sending messages back and forth without stopping (presumably some sort of retry logic).

		message := conn.NewMessage(coap.MessageParams{
			Type:      coap.Confirmable,
			Code:      codes.GET,
			MessageID: uint16(rand.Intn(65535)),
			Token:     []byte{123},
		})
		message.SetOption(coap.ContentFormat, coap.TextPlain)
		message.SetURIQuery("APIKEY=123456")
		message.SetPathString("/test")

		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
		defer cancel()

		err := conn.WriteMsgWithContext(ctx, message)
		if err != nil {
			log.Error().Msgf("Error sending request: %v", err)
			break
		}

BlockwiseResponseWriter doesn't implement .Write()

I just had some fun trying to work out why blockwise transfers weren't working in a test app where the response was handled by:

func handleA(w coap.ResponseWriter, req *coap.Request) {
	w.SetContentFormat(coap.TextPlain)
	if _, err := w.Write(make([]byte, 96)); err != nil {
		log.Printf("Cannot send response: %v", err)
	}
}

The symptoms were that the first block of the response was correctly sent, but the client's request for the second block was silently ignored.

This seems to be because processResp() was failing silently due to resp.Code() != s.expectedCode - where the response code is a POST but the expectedCode is apparently a Continue. However, the correct code for requesting a continuation of a POST is a POST, not a Continue.

This seems to be due to Write() taking completely the wrong path when called on a blockwise transfer; compare:

github.com/go-ocf/go-coap.(*blockWiseSession).sendPayload(0xc0001f0010, 0x5f021701, 0x125efc0, 0xc00019a460, 0x1, 0xc0001c3af8, 0x10adc54, 0xc0000aa000)
	/Users/matthew/go/src/github.com/go-ocf/go-coap/blockwise.go:301 +0x34
github.com/go-ocf/go-coap.(*blockWiseSession).Exchange(0xc0001f0010, 0x125efc0, 0xc00019a460, 0x100, 0x3c, 0x14, 0x3ce189)
	/Users/matthew/go/src/github.com/go-ocf/go-coap/blockwise.go:347 +0x246
github.com/go-ocf/go-coap.(*blockWiseSession).WriteMsg(0xc0001f0010, 0x125efc0, 0xc00019a460, 0xc0001c3b40, 0x10adeb0)
	/Users/matthew/go/src/github.com/go-ocf/go-coap/blockwise.go:357 +0xaf
github.com/go-ocf/go-coap.(*ClientCommander).WriteMsg(0xc0001f0040, 0x125efc0, 0xc00019a460, 0x0, 0x28)
	/Users/matthew/go/src/github.com/go-ocf/go-coap/clientcommander.go:106 +0x47
github.com/go-ocf/go-coap.(*responseWriter).WriteMsg(0xc0001aa140, 0x125efc0, 0xc00019a460, 0x1, 0x1)
	/Users/matthew/go/src/github.com/go-ocf/go-coap/responsewriter.go:60 +0x8b
github.com/go-ocf/go-coap.(*responseWriter).Write(0xc0001aa140, 0xc00020e000, 0x60, 0x60, 0x0, 0x0, 0x0)
	/Users/matthew/go/src/github.com/go-ocf/go-coap/responsewriter.go:88 +0xfd
main.handleA(0x125dda0, 0xc0001a2020, 0xc0001aa160)
	/Users/matthew/workspace/go-ocf/go-coap/examples/simple/test/main.go:29 +0xba
github.com/go-ocf/go-coap.HandlerFunc.ServeCOAP(0x1234c88, 0x125dda0, 0xc0001a2020, 0xc0001aa160)

with instead calling WriteMsg(), which goes straight to a BlockwiseResponseWriter which then does the right thing:

github.com/go-ocf/go-coap.(*blockWiseSession).sendPayload(0xc0001c4010, 0xc002021701, 0x125f040, 0xc0000b8730, 0x1, 0x1259e08, 0xc0001a1ba0, 0x1040927)
	/Users/matthew/go/src/github.com/go-ocf/go-coap/blockwise.go:301 +0x34
github.com/go-ocf/go-coap.(*blockWiseResponseWriter).WriteMsg(0xc0000ac068, 0x125f040, 0xc0000b8730, 0x60, 0x60)
	/Users/matthew/go/src/github.com/go-ocf/go-coap/blockwise.go:756 +0x215
main.handleA(0x125de20, 0xc0000ac068, 0xc0000b6520)
	/Users/matthew/workspace/go-ocf/go-coap/examples/simple/test/main.go:24 +0x13c

I assume this is because blockWiseResponseWriter simply doesn't implement .Write(), causing much confusion.

The workaround is to use .WriteMsg(), which seems to work:

func handleA(w coap.ResponseWriter, req *coap.Request) {
	resp := w.NewResponse(coap.Content)
	resp.SetOption(coap.ContentFormat, coap.TextPlain)
	resp.SetPayload(make([]byte, 96))
	err := w.WriteMsg(resp)
	if err != nil {
		log.Printf("Cannot write response %v", err)
	}
}

Is my reasoning correct here?

mcast server - received RST processed as request?

Testing with the mcast server, I got some irritating behavior:

When I reject a message by sending a RST, that seems to be interpreted as request and a response is sent back. Usually I would expect, that a RST is either ignored or stops some messages from being send again. With the behavior above, the RST seems to achieve the opposite of the intention (stop send that message turns into send new response).

Maybe it's possible to improve the request handler to only forward request (and no ACK/RST/responses as requests). Such a request is either CON or NON message (never ACK nor RST) and the code has class 0.

(Just to mention: the reason for sending RST seems to be, that the endpoint's port is changing (from mcast receiver 5688 to some other port when sending the response). I'm not sure, why this should be accepted, even if the RFC 7252 seems to address that port change. I'm currently try to clarify that. But anyway, processing a RST as request and sending back a response seems to be very irritating.)

Go Modules support

Hi there!

With the introduction of Go 1.11 Modules were introduced. Do you plan to support those?

I can happily submit a PR. It's usually as easy as running

go mod init github.com/axiomhq/quantiles
go mod tidy

Socket not connected error

coap.Dial("udp", "californium.eclipse.org:5683") and fetching any resource leads to the following error on macOS:

2018/12/06 23:39:57 Error sending request: write udp 192.168.2.103:63670: sendmsg: socket is not connected

The server itself works flawless when using for example cf-browser. Switching to tcp delivers the first bytes of the resource, truncating most of it. For example when requesting /:

Correct response via cf-browser and udp:

************************************************************
CoAP RFC 7252                              Cf 2.0.0-SNAPSHOT
************************************************************
This server is using the Eclipse Californium (Cf) CoAP framework
published under EPL+EDL: http://www.eclipse.org/californium/

(c) 2014, 2015, 2016 Institute for Pervasive Computing, ETH Zurich and others
************************************************************

But what I get using go-coap and tcp:

************************************************************
CoA

I double checked using wireshark that cf-browser is using udp and it does. Also both correctly use IPv4 and since both run on the same machine so it is probably NOT some weird networking issue on my machine but something in the code.

This is what happens on the wire with udp and go-coap:

    1   0.000000 192.168.2.103 → 104.196.15.150 CoAP 54 CON, MID:2, GET, TKN:cc 45 ff 95 bf 4f fb 13
    2   0.115109 104.196.15.150 → 192.168.2.103 CoAP 125 ACK, MID:2, 2.05 Content, TKN:cc 45 ff 95 bf 4f fb 13, Block #0 (text/plain)
    3   0.115268 192.168.2.103 → 104.196.15.150 CoAP 57 CON, MID:3, GET, TKN:cc 45 ff 95 bf 4f fb 13, Block #1
    4   0.228254 104.196.15.150 → 192.168.2.103 CoAP 122 ACK, MID:3, 2.05 Content, TKN:cc 45 ff 95 bf 4f fb 13, Block #1 (text/plain)

and this is what is sent by cf-browser:

5  65.229130 192.168.2.103 → 104.196.15.150 CoAP 79 CON, MID:59437, GET, TKN:5d 6c 4b c6 39 07 3e 67, coap://californium.eclipse.org
    6  65.343231 104.196.15.150 → 192.168.2.103 CoAP 125 ACK, MID:59437, 2.05 Content, TKN:5d 6c 4b c6 39 07 3e 67, Block #0, coap://californium.eclipse.org (text/plain)
    7  65.343827 192.168.2.103 → 104.196.15.150 CoAP 82 CON, MID:59438, GET, TKN:5d 6c 4b c6 39 07 3e 67, End of Block #1, coap://californium.eclipse.org
    8  65.455554 104.196.15.150 → 192.168.2.103 CoAP 122 ACK, MID:59438, 2.05 Content, TKN:5d 6c 4b c6 39 07 3e 67, Block #1, coap://californium.eclipse.org (text/plain)
    9  65.456183 192.168.2.103 → 104.196.15.150 CoAP 82 CON, MID:59439, GET, TKN:5d 6c 4b c6 39 07 3e 67, End of Block #2, coap://californium.eclipse.org
   10  65.571477 104.196.15.150 → 192.168.2.103 CoAP 122 ACK, MID:59439, 2.05 Content, TKN:5d 6c 4b c6 39 07 3e 67, Block #2, coap://californium.eclipse.org (text/plain)
   11  65.571985 192.168.2.103 → 104.196.15.150 CoAP 82 CON, MID:59440, GET, TKN:5d 6c 4b c6 39 07 3e 67, End of Block #3, coap://californium.eclipse.org
   12  65.684011 104.196.15.150 → 192.168.2.103 CoAP 122 ACK, MID:59440, 2.05 Content, TKN:5d 6c 4b c6 39 07 3e 67, Block #3, coap://californium.eclipse.org (text/plain)
   13  65.684607 192.168.2.103 → 104.196.15.150 CoAP 82 CON, MID:59441, GET, TKN:5d 6c 4b c6 39 07 3e 67, End of Block #4, coap://californium.eclipse.org
   14  65.798476 104.196.15.150 → 192.168.2.103 CoAP 122 ACK, MID:59441, 2.05 Content, TKN:5d 6c 4b c6 39 07 3e 67, Block #4, coap://californium.eclipse.org (text/plain)
   15  65.799167 192.168.2.103 → 104.196.15.150 CoAP 82 CON, MID:59442, GET, TKN:5d 6c 4b c6 39 07 3e 67, End of Block #5, coap://californium.eclipse.org
   16  65.911070 104.196.15.150 → 192.168.2.103 CoAP 122 ACK, MID:59442, 2.05 Content, TKN:5d 6c 4b c6 39 07 3e 67, Block #5, coap://californium.eclipse.org (text/plain)
   17  65.911650 192.168.2.103 → 104.196.15.150 CoAP 82 CON, MID:59443, GET, TKN:5d 6c 4b c6 39 07 3e 67, End of Block #6, coap://californium.eclipse.org
   18  66.023534 104.196.15.150 → 192.168.2.103 CoAP 122 ACK, MID:59443, 2.05 Content, TKN:5d 6c 4b c6 39 07 3e 67, End of Block #6, coap://californium.eclipse.org (text/plain)

The packets are different but this is also the case for coap.me server and there go-coap works.

Sorry for generating work :)

Client and Client Commander should perhaps implement interfaces to enable mocking for testing

It is very hard to test applications that use the libs as many of the fields/funcions of the Client and other types are structs with unexported fields etc. Nor do they have interfaces so if we nee to test there is no way to mock their behaviour.

I realise this issue is way too broad but I was wondering the reasoning behind some of the unexported fields/non interfaces. I would be happy to do PR's for the changes am making to the library so that I can mock for tests etc if you feel this would be valid.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.