Merge pull request #311 from majestrate/staging

Staging
pull/306/head^2
Jeff 5 years ago committed by GitHub
commit 03b8f1429e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -11,96 +11,79 @@ datagram based network layer.
outer message format: outer message format:
{ outer-header:
A: command,
B: <16 bytes flow id>,
C: <optional 32 bytes cookie>,
X: <N bytes payload>
}
comamnds: <1 byte command>
<1 byte reserved, R, set to '=' (0x3d)>
<32 bytes flow id, B>
A - get handshake cookie
obtain a handshake cookie command 'O' - obtain flow id
B is randomized obtain a handshake cookie
X MUST contain the user agent string of the requester.
the if the network id differs from the current network's id a reject message is <outer-header>
sent: <32 bytes random>
<8 bytes net id>
<remaining discarded>
{ the if the network id differs from the current network's id a reject message
A: R, MUST be sent
B: msg.B,
X: "<reply line>"
}
MUST be replied to with a message rejected or a give handshake cookie MUST be replied to with a message rejected or a give handshake cookie
C - give handshake cookie command 'G' - give flow id
give a handshake cookie to a remote endpoint that asks for one <outer-header>
<32 byte new flow-id, X>
<remaining discarded>
B is the B value from the get handshake cookie message give a flow id to a remote endpoint that asks for one
X is a 32 byte handshake cookie, calcuated via:
r = RAND(32)
a = "<ascii representation of ip>" + " " + "<port number>"
X = HS(a + B + r)
R - message rejected B is the B value from the request flow id message
X is a 32 byte the flow id, calcuated via:
B is the flow id from the recipiant r = RAND(32)
X is a reply line a = "::ffff.<ascii representation of ipv4 address>" + ":" + "<port number>"
X = HS(a + B + r + net id)
reject a message with flow id B resulting message:
S - session negotiation "G=<32 byte flowid><32 bytes new flowid>"
negotiate encrypted session after recieving a give flow id message a session negotiation can happen
B is the flow id from the recipiant command 'R' - message rejected
C is the handshake cookie
X is encrypted session negotiation data
D - encrypted data transmission <outer-header>
<N arbitrary bytes reason for rejection>
transmit encrypted data on session reject a message on a flow id
B is the flow id from the recipiant B is the flow id from the recipiant
X is authenticated and encrypted data
BNF:
<reply-line> ::= <status-code> <space> <method> <space> <message>
<status-code> ::= <integer> <digit> <digit>
<word> ::= <letter>+
<message> ::= <word> <space> <word>* | <word>
<method> ::= "COOKIE" | "HANDSHAKE"
<user-agent> ::= <net-id> <space> <protocol-version> <space> <agent-version> resulting message of reject with reason "no you"
<net-id> ::= "lokinet" | "testnet" "R=<32 byte flow-id>no you"
<space> ::= " " command 'S' - session negotiation
<zero> ::= "0" negotiate encrypted session
<integer> ::= "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<digit> ::= <zero> | <integer>
<number> ::= <zero> | <integer> <digit>* <outer-header>
<24 bytes nounce, N>
<encrypted session negotiation data, X>
<last 32 bytes keyed hash, Z>
<agent-version> ::= <number> "." <number> "." <number> B is the flow id from the recipiant generated by the give flow id message (from outer header)
N is a random nounce
X is encrypted session negotiation data
Z is a keyed hash
<protocol-version> ::= <number> Z is generated via:
msg.Z = '0x00' * 32
msg.Z = MDS(msg, tx_K)
session negotiation: session negotiation:
@ -119,15 +102,9 @@ a.tx_K = k_b
b.tx_K = k_a b.tx_K = k_a
inner message format:
<32 bytes blake2s keyed hash of following data>
<24 bytes nounce>
<remaining bytes encrypted payload>
decryption is done via: decryption is done via:
SD(remaining, rx_K, nounce) SD(msg.X, rx_K, msg.N)
encrypted payload is bencoded LIM (see proto_v0.txt) encrypted payload is bencoded LIM (see proto_v0.txt)
@ -147,20 +124,144 @@ b.rx_K = k_b
a.tx_K = k_b a.tx_K = k_b
b.tx_K = k_a b.tx_K = k_a
afterwards data transmission may happen afterwards data transmission may happen.
the intiator's remote address is permitted to change during data transmission.
remote address of the last successfully
data tranmission: D - encrypted data transmission
message format: transmit encrypted data on session
<10 byte header> <outer-header>
<remaining data payload> <24 bytes nonce, N>
<encrypted data, X>
<last 32 bytes keyed hash of entire payload, Z>
header format:
<1 byte proto version> B is the flow id from the recipiant (from outer header)
N is a random nounce
X is encrypted data
Z is keyed hash of entire message
Z is generated via:
msg.Z = '0x00' * 32
msg.Z = MDS(msg, tx_K)
data tranmission:
inner message format of X (after decryption):
header:
<1 byte protocol version>
<1 byte command> <1 byte command>
<1 byte flags>
<1 byte fragno>
<2 bytes fraglen> command: 'K' (keep alive)
<4 bytes seqno>
tell other side to acknoledge they are alive
<header>
<2 bytes resevered, set to 0>
<2 bytes attempt counter, set to 0 and incremented every retransmit, reset when we get a keepalive ack>
<2 bytes milliseconds ping timeout>
<8 bytes current session TX limit in bytes per second>
<8 bytes current session RX use in bytes per second>
<8 bytes milliseconds since epoch our current time>
<remaining bytes discarded>
command: 'L' (keep alive ack)
acknolege keep alive message
<header>
<6 bytes reserved, set to 0>
<8 bytes current session RX limit in bytes per second>
<8 bytes current session TX use in bytes per second>
<8 bytes milliseconds since epoch our current time>
<remaining bytes discarded>
command: 'C' (congestion)
tell other side to slow down
<header>
<2 bytes reduce TX rate by this many 1024 bytes per second>
<4 bytes milliseconds slowdown lifetime>
<remaining bytes discarded>
command: 'D' (anti-congestion)
tell other side to speed up
<header>
<2 bytes increase TX rate by this many 1024 bytes per second>
<4 bytes milliseconds speedup lifetime>
<remaining bytes discarded>
command: 'T' (transmit)
transit fragment
<header>
<1 byte number of 16 byte blocks offset from beginning of message, O>
<1 byte number of 16 byte blocks size of fragment data, N>
<4 bytes sequence number>
<32 bytes expected digest of message, present if O is 0, otherwise omitted>
<16 * N bytes of data>
<remaining bytes discarded>
command: 'A' (ack)
acknoledge fragments
<header>
<1 byte number of acks following, N>
<8 * N bytes acks>
<remaining bytes discarded>
ack format:
<4 byte message sequence number>
<1 byte reserved current set to 0>
<1 byte ack counter (number of acks sent for the corrisponding message)>
<1 byte bitmask fragments selective ack (msb is fragment 0, lsb is fragment 7)>
<1 byte bitmask fragments posative ack (msb is fragment 0, lsb is fragment 7)>
command: 'R' (rotate keys)
inform remote that their RX key should be rotated
given alice(A) sends this message to bob(B) the new keys are computed as such:
n_K = TKE(K, B_e, K_seed, N)
A.tx_K = n_K
B.rx_K = n_K
<2 bytes milliseconds lifetime of old keys, retain them for this long and then discard>
<4 bytes reserved, set to 0>
<32 bytes key exchange nounce, N>
<32 bytes next public encryption key, K>
<remaining bytes discarded>
command: 'U' (upgrade)
request protocol upgrade
<header>
<1 byte protocol min version to upgrade to>
<1 byte protocol max version to upgrade to>
<remaining bytes discarded>
command: 'V' (version upgrade)
sent in response to upgrade message
<header>
<1 byte protocol version selected>
<1 byte protocol version highest we support>
<remaining bytes discarded>

@ -337,7 +337,9 @@ namespace llarp
link->HandleTimeout(session); link->HandleTimeout(session);
llarp::LogError(utp_error_code_names[arg->error_code], " via ", llarp::LogError(utp_error_code_names[arg->error_code], " via ",
session->remoteAddr); session->remoteAddr);
if(arg->error_code != UTP_ETIMEDOUT) if(arg->error_code == UTP_ETIMEDOUT)
utp_close(arg->socket);
else
session->Close(); session->Close();
link->RemovePending(session); link->RemovePending(session);
} }
@ -872,6 +874,7 @@ namespace llarp
else else
{ {
llarp::LogWarn("utp_socket got data with no underlying session"); llarp::LogWarn("utp_socket got data with no underlying session");
utp_shutdown(arg->socket, SHUT_RDWR);
utp_close(arg->socket); utp_close(arg->socket);
} }
return 0; return 0;

Loading…
Cancel
Save