RIS Live Manual

RIS Live provides real-time JSON BGP messages via a fully filterable interactive WebSocket JSON API, and a full stream ("firehose") containing all of the messages generated by RIS. If you find any bugs or inconsistencies then please send an email to rislive@ripe.net.

Authentication and limits

RIS Live does not currently require any authentication. This may change at a later stage.

If a client is unable to keep up with the incoming data, then a final error message will be sent and the connection will be closed.

Although not required, it is highly recommended to include ?client=<some-meaningful-identifier> in all URLs. This will make it easier for us to identify your application and help you to debug any issues that may arise.

WebSocket interface

The WebSocket interface is a two-way message API that allows you to subscribe to one or more filters. It is available at wss://ris-live.ripe.net/v1/ws/. WebSocket support is included in every major web browser, and is available in all major programming languages via various libraries.

Unlike low-level network sockets, WebSockets are message-based rather than packet-based. In RIS Live, all messages are formatted as JSON objects containing a type key that shows what sort of message it is, and a data key containing the payload. After creating a RIS Live WebSocket you should send a JSON message indicating a set of filters that you wish to subscribe to. The server will then start sending you messages corresponding to BGP messages that match your filters, again in a well defined JSON format. Below is a JavaScript example that outputs every routing announcement seen by RRC21 that involves a transit through a Level 3 ASN. You can try it yourself by opening the JavaScript/Web Console in your browser and entering the following:

var ws = new WebSocket("wss://ris-live.ripe.net/v1/ws/?client=js-manual-example");
ws.onmessage = function(message) {
    var parsed = JSON.parse(message.data);
    console.log(parsed.data);
};
ws.onopen = function() { 
    ws.send(JSON.stringify({type: "ris_subscribe", data: {host: "rrc21", path: 3356}}));
};

This is a simple example in Python that uses the 'websocket-client' library to do the same thing as above:

import json
import websocket

ws = websocket.WebSocket()
ws.connect("wss://ris-live.ripe.net/v1/ws/?client=py-manual-example")
ws.send(json.dumps({"type": "ris_subscribe", "data": {"host": "rrc21", "path": 3356}}))
for data in ws:
    parsed = json.loads(data)
    print(parsed["type"], parsed["data"])

Streaming interface ("firehose")

The streaming interface is designed for researchers and other users who want to monitor real-time RIS data with as little effort as possible. The basic structure of the messages is the same as in the WebSocket interface, but you are not able to subscribe to multiple sets of filters or change your subscriptions during the connection. It is available at the URL https://ris-live.ripe.net/v1/stream/?format=<format>. Once connected, the server will immediately begin sending representations of BGP messages, and will continue until the connection is closed.

In principle, you can access the stream using any programming language or tool that supports HTTP. The available output formats are json and sse.

json messages include a type and a data key containing the BGP message. This is exactly the same format used in the WebSocket interface:

$ curl -s "https://ris-live.ripe.net/v1/stream/?format=json&client=cli-example-1"
{"type":"ris_message","data":{"timestamp":1549982565.19,"peer":"80.249.208.189","peer_asn":"20562","id":"21-80-249-208-189 ...

sse messages are in the Server-Sent Events format, which is part of the HTML 5 standard. The event field corresponds to the type in the WebSocket interface.

$ curl -s "https://ris-live.ripe.net/v1/stream/?format=sse&client=cli-example-2"
event: ris_message
data: {"timestamp":1549983011.99,"peer":"80.81.192.30","peer_asn":"3257" ...

The default subscription for the streaming interface includes all messages with the includeRaw flag, which is the full RIS stream. It is possible to specify a different, more limited subscription by including a X-RIS-Subscribe header, containing a JSON-encoded object with the same format as the payload of the ris_subscribe message.

$ curl -s "https://ris-live.ripe.net/v1/stream/?format=json" -H 'X-RIS-Subscribe: {"path": 3333, "prefix": "193.0.0.0/21"}'

Protocol description

RIS Live uses a message-based protocol where each message has a type and a payload.

RIS Live message (object) {✓✗}

Example:

{"type":"pong","data":null}

Properties:

type (string) (required)

  • RIS Live message type

data (optional)

  • RIS Live message payload. The contents (if any) depend on the `type`.

Client message

The following message types can be sent by the client to the server:

RIS Live client message (object) {✓✗}

Example:

{"type":"ping","data":null}

Properties:

type (string) (required)

  • Client message type

  • Possible values: "ris_subscribe" "ris_unsubscribe" "request_rrc_list" "ping"

data (optional)

  • Client message payload. The contents (if any) depend on the `type`.

ris_subscribe

data (object) {✓✗}

  • Instructs the server to start sending `ris_message` messages matching the given filters

Example:

{"host":"rrc01","type":"UPDATE","require":"announcements","path":"64496,64497$"}

Properties for data:

host (string) (optional)

  • Only include messages collected by a particular RRC

type (string) (optional)

  • Only include messages of a given BGP or RIS type

  • Possible values: "UPDATE" "OPEN" "NOTIFICATION" "KEEPALIVE" "RIS_PEER_STATE"

require (string) (optional)

  • Only include messages containing a given key

Example:

"announcements"

"withdrawals"

peer (string) (optional)

  • Only include messages sent by the given BGP peer

Any of:

path (optional)

  • ASN or pattern to match against the AS PATH attribute

Any of:

ASN (integer)

AS path pattern (string)

  • Comma-separated pattern describing all or part of the AS path. Can optionally begin with ^ to match the first item of the path (the last traversed ASN), and/or end with $ to match the last item of the path (the originating ASN). The entire pattern can be prefixed with ! to invert the match. AS_SETs should be written as JSON arrays of integers in ascending order and with no spaces. Note: this is not a regular expression

Example:

"789$"

"^123,456,789,[789,10111]$"

"!6666$"

"!^3333"

prefix (optional)

  • Filter UPDATE messages by prefixes in announcements or withdrawals

Any of:

IPv4 or IPv6 CIDR prefix (string)

Array of CIDR prefixes (array)

  • For the purposes of subsequent `ris_unsubscribe` messages, each prefix results in a separate subscription that can be stopped independently

Array items:

IPv4 or IPv6 CIDR prefix (string)

moreSpecific (boolean) (optional)

  • Match prefixes that are more specific (part of) `prefix`

  • Default: true

lessSpecific (boolean) (optional)

  • Match prefixes that are less specific (contain) `prefix`

  • Default: false

socketOptions (object) (optional)

  • Options that apply to all subscriptions over the current WebSocket. If a new subscription contains `socketOptions` it will override those from previous subscriptions

Properties for socketOptions:

includeRaw (boolean) (optional)

  • Include a Base64-encoded version of the original binary BGP message as `raw` for all subscriptions

  • Default: false

acknowledge (boolean) (optional)

  • Send a `ris_subscribe_ok` message for all succesful subscriptions

  • Default: false


ris_unsubscribe

data (object) {✓✗}

  • Instructs the server to stop sending messages from a previous `ris_subscribe` message. The provided keys must exactly match the filters given for a previous subscription

request_rrc_list

data (array) {✓✗}

  • A list of available RIS Route Collector hostnames that may appear in the `host` field of RIS messages

ping

data (null) {✓✗}

  • Send in response to a `ping` message

Server messages

The following messages can be sent by the server to the client:

RIS Live server message (object) {✓✗}

Example:

{"type":"pong","data":null}

Properties:

type (string) (required)

  • Server message type

  • Possible values: "ris_message" "ris_error" "ris_rrc_list" "ris_subscribe_ok" "pong"

data (optional)

  • Server message payload. The contents (if any) depend on the `type`.

ris_message

Message from a particular RIS Route Collector data (object) {✓✗}

  • Either a BGP message relayed from a peered router, or a metadata update from a route collector. All ris_message objects have these fields, regardless of subtype, which is given as `type` and corresponds to a particular BGP message type

Example:

{"timestamp":1568279357.18,"peer":"192.0.2.0","peer_asn":"64496","id":"21-192-0-2-0-11187052","host":"rrc21","type":"KEEPALIVE"}

Properties for data:

timestamp (number) (required)

  • Time that the message was received by the RIS Route Collector

peer (required)

  • IP address of the BGP peer that sent this message

Any of:

IPv4 address (string)

IPv6 address (string)

peer_asn (string) (required)

  • Autonomous system of the peer that sent this message

Example:

"65536"

id (string) (required)

  • Globally unique identifier for this message, guaranteed to be sequentially sortable with respect to a particular RIS peering session

raw (string) (optional)

  • Hexadecimal encoding of the raw BGP message in network order, only present if `socketOptions.includeRaw` is true

Example:

"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0072020000005B4001010040020E02030000F09B00001B1B0000316EC0081466321B1B6632FDF36632FE586632FE6C6632FE9D800E2C00020120200112F8000000000000000002230139FE80000000000000CE2DE0FFFE1E5D040030200107FBFD03"

host (string) (required)

  • Hostname of the RIS Route Collector that received this message

type (string) (required)

  • Possible values: "UPDATE" "KEEPALIVE" "OPEN" "NOTIFICATION" "RIS_PEER_STATE"

Additionally, the following fields are type-dependent:

BGP UPDATE Message data (object) {✓✗}

Example:

{"timestamp":1568279796.63,"peer":"192.0.2.0","peer_asn":"64496","id":"21-192-0-2-0-11188782","host":"rrc21","type":"UPDATE","path":[1,2,3,4],"announcements":[{"next_hop":"192.0.2.0","prefixes":["192.0.3.0/24"]}]}

Properties for data:

type (string) (required)

  • Constant value: "UPDATE"

path (array) (optional)

  • ASNs from the AS_PATH attribute, starting with the first upstream, possibly ending in an AS_SET

Example:

[1,2,3,4]

[1,2,3,[64496,64497]]

Array items for path:

Any of:

ASN (integer)

  • 16- or 32-bit ASN

AS_SET (array)

  • AS SET represented as an array of integers in ascending numerical order

Array items:

ASN (integer)

  • 16- or 32-bit ASN

community (array) (optional)

Example:

[[64496,1111],[64497,2222]]

Array items for community:

community attribute (array)

  • COMMUNITY path attribute pairing an ASN with a community value

Tuple members:

ASN (integer)

community value (integer)

origin (string) (optional)

  • ORIGIN path attribute, if present

  • Possible values: "igp" "incomplete" "egp"

med (integer) (optional)

  • MULTI_EXIT_DISC path attribute, if present

aggregator (string) (optional)

  • AGGREGATOR path attribute, if present

Example:

"64496:192.0.2.0"

announcements (array) (optional)

Example:

[{"next_hop":"192.0.2.0","prefixes":["192.0.3.0/24","192.0.4.0/24","192.0.5.0/24"]},{"next_hop":"2001:db8::","prefixes":["2001:db8:420::/48","2001:db8:1010::/48","2001:db8::/32"]}]

Array items for announcements:

announcement (object)

Properties:

next_hop (required)

Any of:

IPv4 address (string)

IPv6 address (string)

prefixes (array) (required)

Array items for prefixes:

IPv4 or IPv6 CIDR prefix (string)

withdrawals (array) (optional)

Example:

["192.0.3.0/24","192.0.4.0/24","192.0.5.0/24","2001:db8:420::/48","2001:db8:1010::/48","2001:db8::/32"]

Array items for withdrawals:

IPv4 or IPv6 CIDR prefix (string)


BGP KEEPALIVE Message data (object) {✓✗}

Example:

{"timestamp":1568284616.24,"peer":"192.0.2.0","peer_asn":"64496","id":"21-192-0-2-0-53776312","host":"rrc00","type":"KEEPALIVE"}

Properties for data:

type (string) (required)

  • Constant value: "KEEPALIVE"

BGP OPEN Message data (object) {✓✗}

Example:

{"timestamp":1568365292.84,"peer":"192.0.2.1","peer_asn":"64496","id":"00-192-0-2-0-180513","host":"rrc00","type":"OPEN","direction":"sent","version":4,"asn":65536,"hold_time":180,"router_id":"192.0.3.1","capabilities":{"1":{"name":"multiprotocol","families":["ipv4/unicast","ipv6/unicast"]},"65":{"name":"asn4","asn4":65536}}}

Properties for data:

type (string) (required)

  • Constant value: "OPEN"

direction (string) (required)

  • Possible values: "sent" "received"

version (integer) (required)

  • Possible values: 4 6

asn (integer) (required)

hold_time (integer) (required)

router_id (string) (required)

capabilities (object) (required)


BGP NOTIFICATION Message data (object) {✓✗}

Example:

{"timestamp":1568365292.84,"peer":"192.0.2.1","peer_asn":"64496","id":"00-192-0-2-0-180513","host":"rrc00","type":"NOTIFICATION","notification":{"code":6,"subcode":7,"data":"0605"}}

Properties for data:

type (string) (required)

  • Constant value: "NOTIFICATION"

notification (object) (required)

Properties for notification:

code (integer) (required)

subcode (integer) (optional)

data (string) (optional)


RIS Peer State Change Message data (object) {✓✗}

Example:

{"timestamp":1568365292.84,"peer":"192.0.2.1","peer_asn":"64496","id":"00-192-0-2-0-180513","host":"rrc00","type":"RIS_PEER_STATE","state":"connected"}

Properties for data:

type (string) (required)

  • Constant value: "RIS_PEER_STATE"

state (string) (required)

  • Possible values: "connected" "up" "down"

ris_error

data (object) {✓✗}

  • You should remember to monitor messages of this type because they are useful in developing robust applications and debugging issues. They may be sent at any time there is a user or server error, including when you send an invalid message to the server.

Properties for data:

message (string) (required)

  • Human-readable message describing the error

ris_rrc_list

data (null) {✓✗}

  • Instructs the server to send a `ris_rrc_list` message with a list of the available RRC hosts, and to resend every time the list changes.

ris_subscribe_ok

data (object) {✓✗}

  • Sent after a successful `ris_subscribe` if `socketOptions.acknowledge` is true.

Properties for data:

subscription (object) (required)

  • The user-supplied parameters of the successful subscription, excluding `socketOptions`

socketOptions (object) (required)

  • The (possibly modified) set of currently applied socket options

pong

data (null) {✓✗}

  • Response to a `ping` message. Note: this is an application-level message to allow you to easily check the connection. The server and client will additionally exchange WebSocket protocol-level 'ping' (0x9) and 'pong' (0xa) control frames to act as heartbeats, but these will usually be handled automatically and transparently.