crosscoap

package module
v0.0.0-...-d24a5da Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 22, 2019 License: Apache-2.0 Imports: 9 Imported by: 0

README

crosscoap

crosscoap is a CoAP (Constrained Application Protocol) UDP server which translates incoming CoAP requests to corresponding HTTP requests which are sent to a backend HTTP server. The HTTP responses from the backend are translated back to CoAP and sent over to the CoAP client.

crosscoap can be used in front of any HTTP server to quickly allow CoAP clients to consume content from that HTTP application, without adding specific CoAP functionality to the application itself.

Install

Go must be installed and $GOPATH properly set. To install crosscoap, run:

go get github.com/ibm-security-innovation/crosscoap/...

This should build the crosscoap executable in $GOPATH/bin.

crosscoap relies on the go-coap library to handle the CoAP packets; it is installed as part of the go get.

Command usage

To proxy incoming CoAP packets (UDP port 5683) to a local HTTP server listening on port 8000:

crosscoap -listen 0.0.0.0:5683 -backend http://127.0.0.1:8000/api

Command-line switches:

  • -listen LISTEN_ADDR_PORT: The address and UDP port on which to listen for incoming CoAP UDP requests (example: 0.0.0.0:5683)
  • -backend BACKEND_URL: The URL of the HTTP backend server (example: http://127.0.0.1:8000/api/v1)
  • -errorlog FILENAME: Log errors to file (default is logging errors to stderr) (example: /tmp/crosscoap-error.log)
  • -accesslog: Log every request to file (example: /tmp/crosscoap-access.log)
Example: fetching Mars weather data over CoAP

The following command will start a CoAP server on UDP port 5683; incoming requests will be translated to HTTP and proxied to the Mars Weather MAAS API service:

crosscoap -listen 0.0.0.0:5683 -backend http://marsweather.ingenology.com/v1 -accesslog /tmp/coap-mars-access.log

Once this is running, you can get the latest Mars weather information with a CoAP client. Here is an example with coap-cli (line breaks were added to the response for clarity):

coap get coap://localhost/latest

(2.05) {"report":
        {"terrestrial_date": "2015-10-12",
         "sol": 1131,
         "ls": 53.0,
         "min_temp": -81.0,
         "min_temp_fahrenheit": -113.8,
         "max_temp": -28.0,
         "max_temp_fahrenheit": -18.4,
         "pressure": 902.0,
         "pressure_string": "Higher",
         "abs_humidity": null,
         "wind_speed": null,
         "wind_direction": "--",
         "atmo_opacity": "Sunny",
         "season": "Month 2",
         "sunrise": "2015-10-12T11:09:00Z",
         "sunset": "2015-10-12T22:55:00Z"}}

In this example, the CoAP request to /latest was proxied to the HTTP backend as http://marsweather.ingenology.com/v1/latest. The backend HTTP server's 200 OK response was translated back to a CoAP 2.05 (Content) response with the CoAP payload holding the JSON document.

Library usage

crosscoap may be used as a Go package in order to add the CoAP proxying functionality to an existing Go application. For example:

package main

import (
        "log"
        "time"
        "net"
        "os"

        "github.com/ibm-security-innovation/crosscoap"
)

func main() {
        timeout := time.Duration(10 * time.Second)
        appLog := log.New(os.Stderr, "", log.LstdFlags)
        udpAddr, err := net.ResolveUDPAddr("udp", "0.0.0.0:5683")
        if err != nil {
                appLog.Fatalln("Can't resolve UDP addr")
        }
        udpListener, err := net.ListenUDP("udp", udpAddr)
        if err != nil {
                errorLog.Fatalln("Can't listen on UDP")
        }
        defer udpListener.Close()
        p := crosscoap.Proxy{
                Listener:   udpListener,
                BackendURL: "http://127.0.0.1:8000/",
                Timeout:    &timeout,
                AccessLog:  appLog,
                ErrorLog:   appLog,
        }
        appLog.Fatal(p.Serve())
}

Notes

CoAP and HTTP are different protocols. crosscoap attempts to translate status codes and headers (options in CoAP) between the two protocols, but not every code and header has a corresponding entity in the other protocol.

CoAP is UDP-based, and therefore the entire CoAP message (UDP headers, CoAP headers and CoAP payload) must fit in the network MTU, which is generally around 1500 bytes. If the response body from the HTTP server is too long, crosscoap will truncate it (and log an error). Keep the HTTP response body under 1400 bytes to be safe.

Alternatives

License

(c) Copyright IBM Corp. 2015, 2016.

This project is licensed under the Apache License 2.0. See the LICENSE file for more info.

3rd party software used by crosscoap:

Contribution

Contributions to the project are welcomed. It is required however to provide alongside the pull request one of the contribution forms (CLA) that are a part of the project. If the contributor is operating in his individual or personal capacity, then he/she is to use the individual CLA; if operating in his/her role at a company or entity, then he/she must use the corporate CLA.

Documentation

Overview

Package crosscoap implements a proxy+translator server that listens for incoming CoAP requests, translates them to HTTP requests which are proxied to the backend, and translates the respones back to CoAP (if the CoAP client request was confirmable).

Example:

package main

import (
	"log"
	"net"
	"os"
	"time"

	"github.com/ibm-security-innovation/crosscoap"
)

func main() {
	timeout := time.Duration(10 * time.Second)
	appLog := log.New(os.Stderr, "[example] ", log.LstdFlags)
	udpAddr, err := net.ResolveUDPAddr("udp", "0.0.0.0:5683")
	if err != nil {
		appLog.Fatalln("Can't resolve UDP addr")
	}
	udpListener, err := net.ListenUDP("udp", udpAddr)
	if err != nil {
		errorLog.Fatalln("Can't listen on UDP")
	}
	defer udpListener.Close()
	p := crosscoap.Proxy{
		Listener:   udpListener,
		BackendURL: "http://127.0.0.1:8000/",
		Timeout:    &timeout,
		AccessLog:  appLog,
		ErrorLog:   appLog,
	}
	appLog.Fatal(p.Serve())
}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ListenAndServe

func ListenAndServe(protocol, addr, backendURL string) error

ListenAndServe listens for incoming CoAP requests on the given protocol and address and proxy them to the HTTP server backendURL.

Types

type Proxy

type Proxy struct {
	// A UDP listener that will accept the incoming CoAP requests.
	Listener *net.UDPConn

	// URL of the HTTP (or HTTPS) backend server to which requests will be
	// proxied.
	BackendURL string

	// Timeout for requests to the HTTP backend.  If nil, a default of 5
	// seconds is used.
	Timeout *time.Duration

	// AccessLog specifies an optional logger which records each incoming
	// request received by the proxy.  If nil, requests are not logged.
	AccessLog *log.Logger

	// ErrorLog specifies an optional logger for errors that occur when
	// attempting to proxy the request.  If nil, error logging goes to
	// os.Stderr via the log package's standard logger.
	ErrorLog *log.Logger
}

Proxy is CoAP server that takes an incoming CoAP request, translates it to an HTTP resquest and sends it to a backend HTTP server; the response it translated back to CoAP and returned to the original client.

func (*Proxy) Serve

func (p *Proxy) Serve() error

Serve starts accepting CoAP requests on the proxy's UDP listener (p.Listener); it never returns (unless there's an error accepting UDP packets or reading them). The server starts a new goroutine to for each incoming UDP CoAP request.

Directories

Path Synopsis
cmd
crosscoap command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL