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