1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
//! Library for parsing cjdns route announcement messages.
//!
//! Each cjdns announcement message contains message header, a sequence of entities and some additional data derived from header.
//! For example, senders auth curve25519 encryption key is derived from the announcement header.
//!
//! # Header
//!
//! The header is 120 bytes long and contains an ed25519 signature over the entire announcement,
//! the public signing key (which is used to create senders auth encryption key using `ed25519 -> curve25519` conversion) of the node which created the announcement, the cjdns IPv6 address of the supernode to which this subnode is announcing,
//! a timestamp, version and a reset flag. On the 03.09.2020 announcement protocol version is `1`.
//!
//! Announcement header packet diagram looks as follows:
//! ```md
//!                        1               2               3
//!        0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
//!       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//!     0 |                                                               |
//!       +                                                               +
//!     4 |                                                               |
//!       +                                                               +
//!     8 |                                                               |
//!       +                                                               +
//!    12 |                                                               |
//!       +                                                               +
//!    16 |                                                               |
//!       +                                                               +
//!    20 |                                                               |
//!       +                                                               +
//!    24 |                                                               |
//!       +                                                               +
//!    28 |                                                               |
//!       +                           Signature                           +
//!    32 |                                                               |
//!       +                                                               +
//!    36 |                                                               |
//!       +                                                               +
//!    40 |                                                               |
//!       +                                                               +
//!    44 |                                                               |
//!       +                                                               +
//!    48 |                                                               |
//!       +                                                               +
//!    52 |                                                               |
//!       +                                                               +
//!    56 |                                                               |
//!       +                                                               +
//!    60 |                                                               |
//!       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//!    64 |                                                               |
//!       +                                                               +
//!    68 |                                                               |
//!       +                                                               +
//!    72 |                                                               |
//!       +                                                               +
//!    76 |                                                               |
//!       +                     Public Signing Key                        +
//!    80 |                                                               |
//!       +                                                               +
//!    84 |                                                               |
//!       +                                                               +
//!    88 |                                                               |
//!       +                                                               +
//!    92 |                                                               |
//!       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//!    96 |                                                               |
//!       +                                                               +
//!   100 |                                                               |
//!       +                        SuperNode IP                           +
//!   104 |                                                               |
//!       +                                                               +
//!   108 |                                                               |
//!       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//!   112 |                                                               |
//!       +                         Timestamp                     +-+-+-+-+
//!   116 |                                                       |R| ver |
//!       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//! ```
//!
//! # Entities
//!
//! Every entity in announcement message begins with two bytes, indicating length and type, at the time of this writing the types of entities are:
//! 1. `EncodingScheme` with type number `0`. The entity contains serialized representation of encoding scheme created by [serializer](../fn.serialize_forms.html). Please look [here](../fn.deserialize_forms.html) for more information about how this is parsed.
//! 2. `Peer` with type number `1`. Each `Peer` entity contains roughly the information which is needed to reach the announcer from a given peer. It is important to note that this is *not* about ability to reach the *peer*, but to reach the announcer if one can already reach said peer.
//! 3. `NodeProtocolVersion` with type number `2`. The entity tells the protocol version of the node sending it.
//! 4. `LinkState` with type number `3`.
//!
//! Entity messages all begin with the length of the entity such that future entities can be added and skipped over by older versions of the parser.
//! Entities longer than 255 or shorter than 1 byte are invalid. If the entity length field is exactly 1 byte, it is a pad and that byte should be skipped over.
//! Pads can be useful to byte-align messages with oddly sized entities.
//!
//! # Example
//! ```rust
//! # use std::convert::TryFrom;
//! # use cjdns_crypto::hash::sha512;
//! # use cjdns_core::{RoutingLabel, EncodingScheme, EncodingSchemeForm};
//! # use cjdns_keys::{CJDNS_IP6, CJDNSPublicKey};
//! # use cjdns_ann::{AnnHash, Announcement, AnnouncementHeader, AnnouncementEntities, Entity, PeerData};
//! use cjdns_ann::AnnouncementPacket;
//! #
//! # let encoding_scheme = |forms| EncodingScheme::try_new(forms).expect("invalid scheme");
//! # let encoding_form = |bit_count, prefix_len, prefix| EncodingSchemeForm::try_new(bit_count, prefix_len, prefix).expect("invalid encoding form");
//! # let announcement_bytes = {
//! #     let hexed_announcement = "3a2349bd342608df20d999ff2384e99f1e179dbdf4aaa61692c2477c011cfe635b42d3cdb8556d94f365cdfa338dc38f40c1fabf69500830af915f41bed71b09f2e1d148ed18b09d16b5766e4250df7b4e83a5ccedd4cfde15f1f474db1a5bc2fc928136dc1fe6e04ef6a6dd7187b85f00001576462f6f69040200120107006114458100200100000000fffffffffffffc928136dc1fe6e04ef6a6dd7187b85f00000015";
//! #     hex::decode(hexed_announcement).expect("invalid hex string")
//! # };
//! # let returning_packet = AnnouncementPacket::try_new(announcement_bytes.clone()).expect("invalid packet length");
//! # let announcement_bytes_hash = sha512::hash(&announcement_bytes);
//!
//! // creating packet
//! let announcement_packet = AnnouncementPacket::try_new(announcement_bytes).unwrap();
//!
//! // checking announcement signature
//! assert!(announcement_packet.check().is_ok());
//!
//! // parsing announcement packet
//! let deserialized_announcement = announcement_packet.parse().unwrap();
//! # assert_eq!(
//! #     deserialized_announcement,
//! #     Announcement {
//! #         header: AnnouncementHeader {
//! #             signature:
//! #                 "3a2349bd342608df20d999ff2384e99f1e179dbdf4aaa61692c2477c011cfe635b42d3cdb8556d94f365cdfa338dc38f40c1fabf69500830af915f41bed71b09"
//! #                     .to_string(),
//! #             pub_signing_key: "f2e1d148ed18b09d16b5766e4250df7b4e83a5ccedd4cfde15f1f474db1a5bc2".to_string(),
//! #             snode_ip: CJDNS_IP6::try_from("fc92:8136:dc1f:e6e0:4ef6:a6dd:7187:b85f").expect("failed ip6 creation"),
//! #             version: 1,
//! #             is_reset: true,
//! #             timestamp: 1474857989878
//! #         },
//! #         entities: vec![
//! #             Entity::NodeProtocolVersion(18),
//! #             Entity::EncodingScheme {
//! #                 hex: "6114458100".to_string(),
//! #                 scheme: encoding_scheme(&vec![
//! #                     encoding_form(3, 1, 1),
//! #                     encoding_form(5, 2, 2),
//! #                     encoding_form(8, 2, 0),
//! #                 ])
//! #             },
//! #             Entity::Peer(PeerData {
//! #                 ipv6: CJDNS_IP6::try_from("fc92:8136:dc1f:e6e0:4ef6:a6dd:7187:b85f").expect("failed ip6 creation"),
//! #                 label: Some(RoutingLabel::<u32>::try_new(21).expect("zero routing label bits")),
//! #                 mtu: 0,
//! #                 peer_num: 65535,
//! #                 unused: 4294967295,
//! #                 encoding_form_number: 0,
//! #                 flags: 0
//! #             })
//! #         ],
//! #         node_pub_key: CJDNSPublicKey::try_from("z15pzyd9wgzs2g5np7d3swrqc1533yb7xx9dq0pvrqrqs42uwgq0.k")
//! #             .expect("failed pub key creation"),
//! #         node_ip: CJDNS_IP6::try_from("fc49:11cb:38c2:8d42:9865:7b8e:0d67:11b3").expect("failed ip6 creation"),
//! #         binary: returning_packet.into_inner(),
//! #         hash: AnnHash::from_digest(announcement_bytes_hash)
//! #     }
//! # );
//!
//! ```
pub use models::{AnnHash, Announcement, AnnouncementEntities, AnnouncementHeader, Entity, LinkStateData, LinkStateSlots, PeerData, LINK_STATE_SLOTS};
pub use serialized_ann::serialized_data::AnnouncementPacket;

mod errors;
mod models;
mod serialized_ann;
mod var_int;