mirror of https://github.com/ntop/n2n.git
Browse Source
* Reimplement JSON mgmt with clear separation of read/write actions * Reduce boilerplate by using a table driven command definition for json mgmt commands * Port tools to use new json api * Add a basic authentication for json mgmt commands * If a auth key is given, it must match * Add auth key to management scripts * Add a flag bitfield to clearly turn the tag param into a options list * Allow simple pass-through of any command from n2nctl * Convert the n2nctl to use an object oriented interface * Handle sigpipe in the n2nhttpd - this happens if the remote client disconnects unexpectely * Remove some repetition from the server * Use the correct options to allow reuseaddr * Dont generate a scary message on ctrl-c * Convert n2nhttpd to use object based RPC * Use the same longopt for both tools * Pass any extra args through to the RPC * Add some documentation for the scripts in the repository * Spelling fix * Add documentation for the JSON reply mangement APIpull/865/head
Hamish Coleman
3 years ago
committed by
GitHub
7 changed files with 629 additions and 125 deletions
@ -0,0 +1,175 @@ |
|||||
|
# Management API |
||||
|
|
||||
|
This document is focused on the machine readable API interfaces. |
||||
|
|
||||
|
Both the edge and the supernode provide a management interface UDP port. |
||||
|
These interfaces have some documentation on their non machine readable |
||||
|
commands in the respective daemon man pages. |
||||
|
|
||||
|
Default Ports: |
||||
|
- UDP/5644 - edge |
||||
|
- UDP/5645 - supernode |
||||
|
|
||||
|
## JSON Query interface |
||||
|
|
||||
|
As part of the management interface, A machine readable API exists for the |
||||
|
edge daemon. It takes a simple text request and replies with JSON formatted |
||||
|
data. |
||||
|
|
||||
|
The request is in simple text so that the daemon does not need to include any |
||||
|
complex parser. |
||||
|
|
||||
|
The replies are all in JSON so that the data is fully machine readable and |
||||
|
the schema can be updated as needed - the burden is entirely on the client |
||||
|
to handle different replies with different fields. It is expected that |
||||
|
any client software will be written in higher level programming languages |
||||
|
where this flexibility is easy to provide. |
||||
|
|
||||
|
Since the API is over UDP, the replies are structured so that each part of |
||||
|
the reply is clearly tagged as belonging to one request and there is a |
||||
|
clear begin and end marker for the reply. This is expected to support the |
||||
|
future possibilities of pipelined and overlapping transactions as well as |
||||
|
pub/sub asynchronous event channels. |
||||
|
|
||||
|
The replies will also handle some small amount of re-ordering of the |
||||
|
packets, but that is not an specific goal of the protocol. |
||||
|
|
||||
|
With a small amount of effort, the API is intended to be human readable, |
||||
|
but this is intended for debugging. |
||||
|
|
||||
|
## Request API |
||||
|
|
||||
|
The request is a single UDP packet containing one line of text with at least |
||||
|
three space separated fields. Any text after the third field is available for |
||||
|
the API method to use for additional parameters |
||||
|
|
||||
|
Fields: |
||||
|
- Message Type |
||||
|
- Options |
||||
|
- Method |
||||
|
- Optional Additional Parameters |
||||
|
|
||||
|
The maximum length of the entire line of text is 80 octets. |
||||
|
|
||||
|
### Message Type |
||||
|
|
||||
|
This is a single octet that is either "r" for a read (or query) method |
||||
|
call or "w" for a write (or change) method call. |
||||
|
|
||||
|
To simplify the interface, the reply from both read and write calls to the |
||||
|
same method is expected to contain the same data. In the case of a write |
||||
|
call, the reply will contain the new state after making the requested change. |
||||
|
|
||||
|
### Options |
||||
|
|
||||
|
The options field is a colon separated set of options for this request. Only |
||||
|
the first subfield (the "tag") is mandatory. The second subfield is a set |
||||
|
of flags that describe which optional subfields are present. |
||||
|
If there are no additional subfields then the flags can be omitted. |
||||
|
|
||||
|
SubFields: |
||||
|
- Message Tag |
||||
|
- Optional Message Flags (defaults to 0) |
||||
|
- Optional Authentication Key |
||||
|
|
||||
|
#### Message Tag |
||||
|
|
||||
|
Each request provides a tag value. Any non error reply associated with this |
||||
|
request will include this tag value, allowing all related messages to be |
||||
|
collected within the client. |
||||
|
|
||||
|
Where possible, the error replies will also include this tag, however some |
||||
|
errors occur before the tag is parsed. |
||||
|
|
||||
|
The tag is not interpreted by the daemon, it is simply echoed back in all |
||||
|
the replies. It is expected to be a short string that the client chooses |
||||
|
to be unique amongst all recent or still outstanding requests. |
||||
|
|
||||
|
One possible client implementation is a number between 0 and 999, incremented |
||||
|
for each request and wrapping around to zero when it is greater than 999. |
||||
|
|
||||
|
#### Message Flags |
||||
|
|
||||
|
This subfield is a set of bit flags that are hex-encoded and describe any |
||||
|
remaining optional subfields. |
||||
|
|
||||
|
Currently, only one flag is defined. The presence of that flag indicates |
||||
|
that an authentication key subfield is also present. |
||||
|
|
||||
|
Values: |
||||
|
- 0 - No additional subfields are present |
||||
|
- 1 - One additional field, containing the authentication key |
||||
|
|
||||
|
#### Authentication Key |
||||
|
|
||||
|
A simple string password that is provided by the client to authenticate |
||||
|
this request. See the Authentication section below for more discussion. |
||||
|
|
||||
|
#### Example Options value |
||||
|
|
||||
|
e.g: |
||||
|
`102:1:PassWord` |
||||
|
|
||||
|
### Example Request string |
||||
|
|
||||
|
e.g: |
||||
|
`r 103:1:PassWord peer` |
||||
|
|
||||
|
## Reply API |
||||
|
|
||||
|
Each UDP packet in the reply is a complete and valid JSON dictionary |
||||
|
containing a fragment of information related to the entire reply. |
||||
|
|
||||
|
### Common metadata |
||||
|
|
||||
|
There are two keys in each dictionary containing metadata. First |
||||
|
is the `_tag`, containing the Message Tag from the original request. |
||||
|
Second is the `_type` whic identifies the expected contents of this |
||||
|
packet. |
||||
|
|
||||
|
### `_type: error` |
||||
|
|
||||
|
If an error condition occurs, a packet with a `error` key describing |
||||
|
the error will be sent. This usually also indicates that there will |
||||
|
be no more substantial data arriving related to this request. |
||||
|
|
||||
|
e.g: |
||||
|
`{"_tag":"107","_type":"error","error":"badauth"}` |
||||
|
|
||||
|
### `_type: begin` |
||||
|
|
||||
|
Before the start of any substantial data packets, a `begin` packet is |
||||
|
sent. For consistency checking, the method in the request is echoed |
||||
|
back in the `error` key. |
||||
|
|
||||
|
e.g: |
||||
|
`{"_tag":"108","_type":"begin","cmd":"peer"}` |
||||
|
|
||||
|
For simplicity in decoding, if a `begin` packet is sent, all attempts |
||||
|
are made to ensure that a final `end` packet is also sent. |
||||
|
|
||||
|
### `_type: end` |
||||
|
|
||||
|
After the last substantial data packet, a final `end` packet is sent |
||||
|
to signal to the client that this reply is finished. |
||||
|
|
||||
|
e.g: |
||||
|
`{"_tag":"108","_type":"end"}` |
||||
|
|
||||
|
### `_type: row` |
||||
|
|
||||
|
The substantial bulk of the data in the reply is contained within one or |
||||
|
more `row` packets. The non metadata contents of each `row` packet is |
||||
|
defined entirely by the method called and may change from version to version. |
||||
|
|
||||
|
e.g: |
||||
|
`{"_tag":"108","_type":"row","mode":"p2p","ip4addr":"10.135.98.84","macaddr":"86:56:21:E4:AA:39","sockaddr":"192.168.7.191:41701","desc":"client4","lastseen":1584682200}` |
||||
|
|
||||
|
## Authentication |
||||
|
|
||||
|
Some API requests will make global changes to the running daemon and may |
||||
|
affect the availability of the n2n networking. Therefore the machine |
||||
|
readable API include an authentication component. |
||||
|
|
||||
|
Currently, the only authentication is a simple password that the client |
||||
|
must provide. |
@ -0,0 +1,41 @@ |
|||||
|
# Scripts |
||||
|
|
||||
|
There are a number of useful scripts included with the distribution. |
||||
|
Some of these scripts are only useful during build and development, but |
||||
|
other scripts are intended for end users to be able to use. These scripts |
||||
|
may be installed with n2n as part of your operating system package. |
||||
|
|
||||
|
Short descriptions of these scripts are below. |
||||
|
|
||||
|
## `scripts/hack_fakeautoconf` |
||||
|
|
||||
|
This shell script is used during development to help build on Windows |
||||
|
systems. An example of how to use it is shown in |
||||
|
the [Building document](Building.md) |
||||
|
|
||||
|
## `tools/test_harness` |
||||
|
|
||||
|
This shell script is used to run automated tests during development. |
||||
|
|
||||
|
## `scripts/n2nctl` |
||||
|
|
||||
|
This python script provides an easy command line interface to the running |
||||
|
edge. It uses UDP communications to talk to the Management API. |
||||
|
|
||||
|
Example: |
||||
|
- `scripts/n2nctl --help` |
||||
|
- `scripts/n2nctl help` |
||||
|
|
||||
|
## `scripts/n2nhttpd` |
||||
|
|
||||
|
This python script is a simple http gateway to the running edge. It provides |
||||
|
a proxy for REST-like HTTP requests to talk to the Management API. |
||||
|
|
||||
|
By default it runs on port 8080. |
||||
|
|
||||
|
It also provides a simple HTML page showing some information, which when |
||||
|
run with default settings can be seen at http://localhost:8080/ |
||||
|
|
||||
|
Example: |
||||
|
- `scripts/n2nhttpd --help` |
||||
|
- `scripts/n2nhttpd 8087` |
Loading…
Reference in new issue