├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── COPYRIGHT ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── appveyor.yml ├── benches ├── socket.rs └── stream.rs ├── examples ├── echo-server.rs └── utpcat.rs ├── src ├── bit_iterator.rs ├── error.rs ├── lib.rs ├── packet.rs ├── socket.rs ├── stream.rs ├── time.rs └── util.rs └── tests └── stream.rs /.gitignore: -------------------------------------------------------------------------------- 1 | doc 2 | target 3 | *.swp 4 | Cargo.lock 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | cache: cargo 3 | sudo: false 4 | addons: 5 | apt: 6 | packages: 7 | - libcurl4-openssl-dev 8 | - libelf-dev 9 | - libdw-dev 10 | rust: 11 | - nightly 12 | - beta 13 | - stable 14 | matrix: 15 | allow_failures: 16 | - rust: nightly 17 | before_script: 18 | - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH 19 | after_success: | 20 | export RUSTFLAGS="$RUSTFLAGS -C link-dead-code" && 21 | travis-cargo --only stable doc && 22 | travis-cargo --only stable doc-upload && 23 | wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz && 24 | tar xzf master.tar.gz && 25 | mv kcov-master kcov 26 | cd kcov && 27 | mkdir build && 28 | cd build && 29 | cmake .. && 30 | make && 31 | cd ../.. && 32 | for file in target/debug/{utp,stream}-*; do mkdir -p "target/cov/$(basename $file)"; kcov/build/src/kcov --exclude-pattern=/.cargo,/usr/lib --verify "target/cov/$(basename $file)" "$file"; done && 33 | bash <(curl -s https://codecov.io/bash) && 34 | echo "Uploaded code coverage" 35 | env: 36 | global: 37 | secure: cqq4PpUsrmCNLbWrmkkuf/SaCKET0+QN5w0lXmuOndBES5C+m/aR417T3Pb+7PR4gqibf47eSXgaVCQa64eZAI5PjgXrdZ7FtPRu/mgcsgcgiVrSUz5C/KSMsmp876Gl67csjCZ6SZXJ3YC0/Jh3jiJLiRt9Giqzn/s1v15j/CY= 38 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## [0.6.3] 4 | 5 | ### Added 6 | 7 | - Added `peer_fn` method to UtpSocket. 8 | 9 | ### Fixed 10 | 11 | - Fixed arithmetic operation overflow when calculating the delay between peers. 12 | - Unconnected sockets and streams no longer send fast resend requests before failing. 13 | 14 | ## [0.6.2] 15 | 16 | ### Fixed 17 | 18 | - Fixed Windows build. 19 | 20 | ## [0.6.1] 21 | 22 | ### Added 23 | 24 | - Packets are resent if no acknowledgment is received before timeout. 25 | - Sockets time out after too many retransmissions (configurable), returning an error. 26 | 27 | ### Fixed 28 | 29 | - Socket creation no longer fails with arithmetic overflow when generating a 30 | random connection identifier. 31 | - SACK extension generation no longer fails with arithmetic overflow. 32 | - Resending lost packets no longer floods the connection. 33 | - Fixed packet extension encoding. 34 | - Many protocol bug fixes. 35 | - Fixed warning about Sized in trait on rustc 1.4.0-nightly (10d69db0a 2015-08-23) (RFC 1214 fallout) 36 | 37 | ## [0.6.0] 38 | 39 | ### Added 40 | 41 | - Implemented the `Deref` trait for easy conversion from `UtpStream` instances into the underlying `UtpSocket`. 42 | 43 | ### Changed 44 | 45 | - `UtpSocket::connect` is now a function instead of a method on a `UtpSocket` instance (i.e., it doesn't require a socket to be called). 46 | 47 | ## [0.5.1] 48 | 49 | ### Added 50 | 51 | - Added `local_addr` for both `UtpSocket` and `UtpStream`. 52 | 53 | ## [0.5.0] 54 | 55 | ### Added 56 | 57 | - Added `local_addr` for both `UtpSocket` and `UtpStream`. 58 | - Added the `Into` trait for easy conversion from `UtpSocket` instances into `UtpStream`. 59 | 60 | ### Changed 61 | 62 | - `UtpListener::accept` now returns both the new socket and the remote peer's address (`Result`), similarly to `TcpListener`. 63 | - `UtpListener::incoming` now also returns the remote peer's address, similarly to `accept` but unlike `TcpListener::incoming`. 64 | 65 | ## [0.4.0] 66 | 67 | ### Added 68 | 69 | - Added `UtpListener` (similar to [`TcpListener`][http://doc.rust-lang.org/std/net/struct.TcpListener.html]). 70 | 71 | ## [0.3.1] 72 | 73 | ### Fixed 74 | 75 | - Removed assertions about `off_target`, which were killing innocent connections. 76 | 77 | ## [0.3.0] 78 | 79 | ### Fixed 80 | 81 | - Fixed bug when adjusting congestion window caused by miscalculating the delay between peers. 82 | - Fixed bug where missing packets weren't being re-sent after sending a FIN. 83 | - Fixed bug where a stream wouldn't bind to an address of the appropriate family when the remote peer had an IPv6 address. 84 | - Fixed bug where the congestion window would only shrink when packet loss was detected and not on delay changes. 85 | 86 | ### Changed 87 | 88 | - A call to `UtpStream::write` or `UtpSocket::send_to` no longer blocks until every packet is acknowledged. To force the old, slower behaviour, call `flush` after the usual calls (usually you won't need to do this, as the socket/stream is flushed on close/drop). 89 | 90 | ## [0.2.8] 91 | 92 | ### Fixed 93 | 94 | - Fixed bug where extensions could be skipped when parsing a packet. 95 | - Improved reliability of packet parsing. 96 | 97 | ## [0.2.7] 98 | 99 | ### Fixed 100 | 101 | - Fixed compilation errors in 1.0.0-beta.2 102 | 103 | ### Changed 104 | 105 | - Improved resilience to errors --- receiving an invalid packet no longer leads to a panic 106 | - Sockets with established connections refuse new connections 107 | 108 | ## [0.2.6] 109 | 110 | No functional changes. 111 | 112 | ### Changed 113 | 114 | - Removed stability attributes. 115 | - Removed an unnecessary partial clone when handling a received packet. 116 | 117 | ## [0.2.5] 118 | 119 | ### Changed 120 | 121 | - Dropping an `UtpSocket` (or a wrapping struct like `UtpStream`) properly closes open connections. 122 | 123 | ## [0.2.4] 124 | 125 | Improved performance encoding and decoding packets. 126 | 127 | ## [0.2.3] 128 | 129 | ### Fixed 130 | - Now the crate builds in both the latest nightly and 1.0.0-beta. 131 | 132 | ## [0.2.2] 133 | 134 | No functional changes, mostly just changes to conform to changes in the Rust API. 135 | 136 | ## [0.2.1] 137 | 138 | ### Changed 139 | - Updated the `rand` dependency because the previous one didn't build on the latest Rust nightly. 140 | 141 | ### Fixed 142 | - Some `UtpStream` tests were failing because of improperly sized buffers. 143 | 144 | ## [0.2.0] 145 | 146 | This release is now compatible with the 2015-03-28 nightly of the Rust compiler. 147 | Some things changed during the migration to the new `std::net` API and performance is now much lower. It might take me a while to come up with performance improvements and a replacement for the lost `set_timeout` method in `UdpSocket`. 148 | 149 | ### Changed 150 | - Updated example in README. 151 | - `UtpStream` and `UtpSocket` now accept variables implementing the `ToSocketAddrs` trait, like `UdpSocket` in the standard library. 152 | - Reading from a socket now returns `Result<(usize, SocketAddr)>`. 153 | - Reading from a stream now returns `Result`. 154 | - Reading from a closed socket/stream now returns `Ok((0, remote_peer))`/`Ok(0)` instead of `Err(Closed)`. 155 | 156 | ### Added 157 | - `UtpStream` now implements the `Read` and `Write` traits. 158 | 159 | ### Removed 160 | - The `Reader` and `Writer` traits were removed, in accordance to the recent IO reform in Rust. 161 | - Support for connection timeouts were removed, which may impact packet loss handling in some cases. 162 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | This project is dual-licensed under the terms of the MIT and Apache (version 2.0) licenses. 2 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["Ricardo Martins "] 3 | description = "A µTP (Micro/uTorrent Transport Library) library implemented in Rust" 4 | documentation = "http://meqif.github.io/rust-utp" 5 | homepage = "https://github.com/meqif/rust-utp" 6 | keywords = ["utp", "networking", "protocol", "transport"] 7 | license = "MIT/Apache-2.0" 8 | name = "utp" 9 | readme = "README.md" 10 | repository = "https://github.com/meqif/rust-utp" 11 | version = "0.7.1-pre" 12 | edition = "2018" 13 | 14 | [badges] 15 | maintenance = { status = "experimental" } 16 | 17 | [dependencies] 18 | log = "0.4.14" 19 | num-traits = "0.2.14" 20 | rand = "0.8.3" 21 | 22 | [dev-dependencies] 23 | quickcheck = "1.0.3" 24 | env_logger = "0.8.3" 25 | 26 | [lib] 27 | name = "utp" 28 | 29 | [features] 30 | unstable = [] 31 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Ricardo Martins 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rust-utp 2 | 3 | [![Crate Version](https://img.shields.io/crates/v/utp.svg?style=flat)](https://crates.io/crates/utp) 4 | [![Build Status](https://img.shields.io/travis/meqif/rust-utp.svg?style=flat)](http://travis-ci.org/meqif/rust-utp) 5 | [![Windows Build Status](https://ci.appveyor.com/api/projects/status/q38b38fendqat8o6?svg=true)](https://ci.appveyor.com/project/meqif/rust-utp) 6 | [![codecov](https://codecov.io/gh/meqif/rust-utp/branch/master/graph/badge.svg)](https://codecov.io/gh/meqif/rust-utp) 7 | [![Dependency Status](https://dependencyci.com/github/meqif/rust-utp/badge)](https://dependencyci.com/github/meqif/rust-utp) 8 | ![Maintenance: experimental](https://img.shields.io/badge/maintenance-experimental-red.svg) 9 | 10 | A [Micro Transport Protocol](http://www.bittorrent.org/beps/bep_0029.html) 11 | library implemented in Rust. 12 | 13 | [API documentation](http://meqif.github.io/rust-utp/) 14 | 15 | ## Overview 16 | 17 | The Micro Transport Protocol is a reliable transport protocol built over 18 | UDP. Its congestion control algorithm is 19 | [LEDBAT](http://tools.ietf.org/html/rfc6817), which tries to use as much unused 20 | bandwidth as it can but readily yields to competing flows, making it useful for 21 | bulk transfers without introducing congestion in the network. 22 | 23 | The current implementation is somewhat incomplete, lacking a complete implementation of congestion 24 | control. However, it does support packet loss detection (except by timeout) the 25 | Selective Acknowledgment extension, handles unordered and duplicate packets and 26 | presents a stream interface (`UtpStream`). 27 | 28 | ## Usage 29 | 30 | To use `utp`, add this to your `Cargo.toml`: 31 | 32 | ```toml 33 | [dependencies] 34 | utp = "*" 35 | ``` 36 | 37 | Then, import it in your crate root or wherever you need it: 38 | 39 | ```rust 40 | extern crate utp; 41 | ``` 42 | 43 | ## Examples 44 | 45 | The simplest example program would be: 46 | 47 | ```rust 48 | extern crate utp; 49 | 50 | use utp::UtpStream; 51 | use std::io::Write; 52 | 53 | fn main() { 54 | // Connect to an hypothetical local server running on port 8080 55 | let addr = "127.0.0.1:8080"; 56 | let mut stream = UtpStream::connect(addr).expect("Error connecting to remote peer"); 57 | 58 | // Send a string 59 | stream.write("Hi there!".as_bytes()).expect("Write failed"); 60 | 61 | // Close the stream 62 | stream.close().expect("Error closing connection"); 63 | } 64 | ``` 65 | 66 | Check out the files under the "examples" directory for more example programs, or run them with `cargo run --example `. 67 | 68 | ## Roadmap 69 | 70 | - [x] congestion control 71 | - [x] proper connection closing 72 | - [x] handle both RST and FIN 73 | - [x] send FIN on close 74 | - [x] automatically send FIN on `drop` if not already closed 75 | - [x] sending RST on mismatch 76 | - [x] setters and getters that hide header field endianness conversion 77 | - [x] SACK extension 78 | - [x] handle packet loss 79 | - [x] send triple-ACK to re-request lost packet (fast resend request) 80 | - [x] rewind send window and resend in reply to triple-ACK (fast resend) 81 | - [x] resend packet on ACK timeout 82 | - [x] stream interface 83 | - [x] handle unordered packets 84 | - [x] duplicate packet handling 85 | - [x] listener abstraction 86 | - [x] incoming connections iterator 87 | - [x] time out connection after too many retransmissions 88 | - [ ] path MTU discovery 89 | 90 | ## License 91 | 92 | This library is distributed under similar terms to Rust: dual licensed under the MIT license and the Apache license (version 2.0). 93 | 94 | See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details. 95 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | install: 2 | - ps: Start-FileDownload 'https://static.rust-lang.org/dist/rust-nightly-i686-pc-windows-gnu.exe' 3 | - rust-nightly-i686-pc-windows-gnu.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust" 4 | - SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin 5 | - SET PATH=%PATH%;C:\MinGW\bin 6 | - rustc -V 7 | - cargo -V 8 | - git submodule update --init --recursive 9 | 10 | build: false 11 | 12 | test_script: 13 | - cargo test --verbose 14 | -------------------------------------------------------------------------------- /benches/socket.rs: -------------------------------------------------------------------------------- 1 | #![feature(test)] 2 | 3 | extern crate test; 4 | extern crate utp; 5 | 6 | use std::sync::Arc; 7 | use std::thread; 8 | use test::Bencher; 9 | use utp::UtpSocket; 10 | 11 | macro_rules! iotry { 12 | ($e:expr) => { 13 | match $e { 14 | Ok(e) => e, 15 | Err(e) => panic!("{}", e), 16 | } 17 | }; 18 | } 19 | 20 | fn next_test_port() -> u16 { 21 | use std::sync::atomic::{AtomicUsize, Ordering}; 22 | static NEXT_OFFSET: AtomicUsize = AtomicUsize::new(0); 23 | const BASE_PORT: u16 = 9600; 24 | BASE_PORT + NEXT_OFFSET.fetch_add(1, Ordering::Relaxed) as u16 25 | } 26 | 27 | fn next_test_ip4<'a>() -> (&'a str, u16) { 28 | ("127.0.0.1", next_test_port()) 29 | } 30 | 31 | #[bench] 32 | fn bench_connection_setup_and_teardown(b: &mut Bencher) { 33 | let server_addr = next_test_ip4(); 34 | let mut buf = [0; 1500]; 35 | 36 | b.iter(|| { 37 | let mut server = iotry!(UtpSocket::bind(server_addr)); 38 | 39 | thread::spawn(move || { 40 | let mut client = iotry!(UtpSocket::connect(server_addr)); 41 | iotry!(client.close()); 42 | }); 43 | 44 | loop { 45 | match server.recv_from(&mut buf) { 46 | Ok((0, _src)) => break, 47 | Ok(_) => (), 48 | Err(e) => panic!("{}", e), 49 | } 50 | } 51 | iotry!(server.close()); 52 | }); 53 | } 54 | 55 | #[bench] 56 | fn bench_transfer_one_packet(b: &mut Bencher) { 57 | let len = 1024; 58 | let server_addr = next_test_ip4(); 59 | let mut buf = [0; 1500]; 60 | let data = (0..len).map(|x| x as u8).collect::>(); 61 | let data_arc = Arc::new(data); 62 | 63 | b.iter(|| { 64 | let data = data_arc.clone(); 65 | let mut server = iotry!(UtpSocket::bind(server_addr)); 66 | 67 | thread::spawn(move || { 68 | let mut client = iotry!(UtpSocket::connect(server_addr)); 69 | iotry!(client.send_to(&data[..])); 70 | iotry!(client.close()); 71 | }); 72 | 73 | loop { 74 | match server.recv_from(&mut buf) { 75 | Ok((0, _src)) => break, 76 | Ok(_) => (), 77 | Err(e) => panic!("{}", e), 78 | } 79 | } 80 | iotry!(server.close()); 81 | }); 82 | b.bytes = len as u64; 83 | } 84 | 85 | #[bench] 86 | fn bench_transfer_one_megabyte(b: &mut Bencher) { 87 | let len = 1024 * 1024; 88 | let server_addr = next_test_ip4(); 89 | let mut buf = [0; 1500]; 90 | let data = (0..len).map(|x| x as u8).collect::>(); 91 | let data_arc = Arc::new(data); 92 | 93 | b.iter(|| { 94 | let data = data_arc.clone(); 95 | let mut server = iotry!(UtpSocket::bind(server_addr)); 96 | 97 | thread::spawn(move || { 98 | let mut client = iotry!(UtpSocket::connect(server_addr)); 99 | iotry!(client.send_to(&data[..])); 100 | iotry!(client.close()); 101 | }); 102 | 103 | loop { 104 | match server.recv_from(&mut buf) { 105 | Ok((0, _src)) => break, 106 | Ok(_) => (), 107 | Err(e) => panic!("{}", e), 108 | } 109 | } 110 | iotry!(server.close()); 111 | }); 112 | b.bytes = len as u64; 113 | } 114 | -------------------------------------------------------------------------------- /benches/stream.rs: -------------------------------------------------------------------------------- 1 | #![feature(test)] 2 | 3 | extern crate test; 4 | extern crate utp; 5 | 6 | use std::io::{Read, Write}; 7 | use std::sync::Arc; 8 | use std::thread; 9 | use test::Bencher; 10 | use utp::UtpStream; 11 | 12 | macro_rules! iotry { 13 | ($e:expr) => { 14 | match $e { 15 | Ok(e) => e, 16 | Err(e) => panic!("{}", e), 17 | } 18 | }; 19 | } 20 | 21 | fn next_test_port() -> u16 { 22 | use std::sync::atomic::{AtomicUsize, Ordering}; 23 | static NEXT_OFFSET: AtomicUsize = AtomicUsize::new(0); 24 | const BASE_PORT: u16 = 9600; 25 | BASE_PORT + NEXT_OFFSET.fetch_add(1, Ordering::Relaxed) as u16 26 | } 27 | 28 | fn next_test_ip4<'a>() -> (&'a str, u16) { 29 | ("127.0.0.1", next_test_port()) 30 | } 31 | 32 | #[bench] 33 | fn bench_connection_setup_and_teardown(b: &mut Bencher) { 34 | let server_addr = next_test_ip4(); 35 | let mut received = vec![]; 36 | b.iter(|| { 37 | let mut server = iotry!(UtpStream::bind(server_addr)); 38 | 39 | thread::spawn(move || { 40 | let mut client = iotry!(UtpStream::connect(server_addr)); 41 | iotry!(client.close()); 42 | }); 43 | 44 | iotry!(server.read_to_end(&mut received)); 45 | iotry!(server.close()); 46 | }); 47 | } 48 | 49 | #[bench] 50 | fn bench_transfer_one_packet(b: &mut Bencher) { 51 | let len = 1024; 52 | let server_addr = next_test_ip4(); 53 | let data = (0..len).map(|x| x as u8).collect::>(); 54 | let data_arc = Arc::new(data); 55 | let mut received = Vec::with_capacity(len); 56 | 57 | b.iter(|| { 58 | let data = data_arc.clone(); 59 | let mut server = iotry!(UtpStream::bind(server_addr)); 60 | 61 | thread::spawn(move || { 62 | let mut client = iotry!(UtpStream::connect(server_addr)); 63 | iotry!(client.write(&data[..])); 64 | iotry!(client.close()); 65 | }); 66 | 67 | iotry!(server.read_to_end(&mut received)); 68 | iotry!(server.close()); 69 | }); 70 | b.bytes = len as u64; 71 | } 72 | 73 | #[bench] 74 | fn bench_transfer_one_megabyte(b: &mut Bencher) { 75 | let len = 1024 * 1024; 76 | let server_addr = next_test_ip4(); 77 | let data = (0..len).map(|x| x as u8).collect::>(); 78 | let data_arc = Arc::new(data); 79 | let mut received = Vec::with_capacity(len); 80 | 81 | b.iter(|| { 82 | let data = data_arc.clone(); 83 | let mut server = iotry!(UtpStream::bind(server_addr)); 84 | 85 | thread::spawn(move || { 86 | let mut client = iotry!(UtpStream::connect(server_addr)); 87 | iotry!(client.write(&data[..])); 88 | iotry!(client.close()); 89 | }); 90 | 91 | iotry!(server.read_to_end(&mut received)); 92 | iotry!(server.close()); 93 | }); 94 | b.bytes = len as u64; 95 | } 96 | -------------------------------------------------------------------------------- /examples/echo-server.rs: -------------------------------------------------------------------------------- 1 | use env_logger; 2 | 3 | use std::thread; 4 | use utp::{UtpListener, UtpSocket}; 5 | 6 | fn handle_client(mut s: UtpSocket) { 7 | let mut buf = [0; 1500]; 8 | 9 | // Reply to a data packet with its own payload, then end the connection 10 | match s.recv_from(&mut buf) { 11 | Ok((nread, src)) => { 12 | println!("<= [{}] {:?}", src, &buf[..nread]); 13 | let _ = s.send_to(&buf[..nread]); 14 | } 15 | Err(e) => println!("{}", e), 16 | } 17 | } 18 | 19 | fn main() { 20 | // Start logger 21 | env_logger::init(); 22 | 23 | // Create a listener 24 | let addr = "127.0.0.1:8080"; 25 | let listener = UtpListener::bind(addr).expect("Error binding listener"); 26 | 27 | for connection in listener.incoming() { 28 | // Spawn a new handler for each new connection 29 | match connection { 30 | Ok((socket, _src)) => { 31 | thread::spawn(move || handle_client(socket)); 32 | } 33 | _ => (), 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /examples/utpcat.rs: -------------------------------------------------------------------------------- 1 | //! Implementation of a simple uTP client and server. 2 | use env_logger; 3 | 4 | use std::process; 5 | 6 | fn usage() -> ! { 7 | println!("Usage: utp [-s|-c]
"); 8 | process::exit(1); 9 | } 10 | 11 | fn main() { 12 | use std::io::{stderr, stdin, stdout, Read, Write}; 13 | use utp::UtpStream; 14 | 15 | // This example may run in either server or client mode. 16 | // Using an enum tends to make the code cleaner and easier to read. 17 | enum Mode { 18 | Server, 19 | Client, 20 | } 21 | 22 | // Start logging 23 | env_logger::init(); 24 | 25 | // Fetch arguments 26 | let mut args = std::env::args(); 27 | 28 | // Skip program name 29 | args.next(); 30 | 31 | // Parse the mode argument 32 | let mode: Mode = match args.next() { 33 | Some(ref s) if s == "-s" => Mode::Server, 34 | Some(ref s) if s == "-c" => Mode::Client, 35 | _ => usage(), 36 | }; 37 | 38 | // Parse the address argument or use a default if none is provided 39 | let addr = match (args.next(), args.next()) { 40 | (None, None) => "127.0.0.1:8080".to_owned(), 41 | (Some(ip), Some(port)) => format!("{}:{}", ip, port), 42 | _ => usage(), 43 | }; 44 | let addr: &str = &addr; 45 | 46 | match mode { 47 | Mode::Server => { 48 | // Create a listening stream 49 | let mut stream = UtpStream::bind(addr).expect("Error binding stream"); 50 | let mut writer = stdout(); 51 | let _ = writeln!(&mut stderr(), "Serving on {}", addr); 52 | 53 | // Create a reasonably sized buffer 54 | let mut payload = vec![0; 1024 * 1024]; 55 | 56 | // Wait for a new connection and print the received data to stdout. 57 | // Reading and printing chunks like this feels more interactive than trying to read 58 | // everything with `read_to_end` and avoids resizing the buffer multiple times. 59 | loop { 60 | match stream.read(&mut payload) { 61 | Ok(0) => break, 62 | Ok(read) => writer 63 | .write(&payload[..read]) 64 | .expect("Error writing to stdout"), 65 | Err(e) => panic!("{}", e), 66 | }; 67 | } 68 | } 69 | Mode::Client => { 70 | // Create a stream and try to connect to the remote address 71 | let mut stream = UtpStream::connect(addr).expect("Error connecting to remote peer"); 72 | let mut reader = stdin(); 73 | 74 | // Create a reasonably sized buffer 75 | let mut payload = vec![0; 1024 * 1024]; 76 | 77 | // Read from stdin and send it to the remote server. 78 | // Once again, reading and sending small chunks like this avoids having to read the 79 | // entire input (which may be endless!) before starting to send, unlike what would 80 | // happen if we were to use `read_to_end` on `reader`. 81 | loop { 82 | match reader.read(&mut payload) { 83 | Ok(0) => break, 84 | Ok(read) => stream 85 | .write(&payload[..read]) 86 | .expect("Error writing to stream"), 87 | Err(e) => { 88 | stream.close().expect("Error closing stream"); 89 | panic!("{:?}", e); 90 | } 91 | }; 92 | } 93 | 94 | // Explicitly close the stream. 95 | stream.close().expect("Error closing stream"); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/bit_iterator.rs: -------------------------------------------------------------------------------- 1 | // How many bits in a `u8` 2 | const U8BITS: usize = 8; 3 | 4 | /// Lazy iterator over bits of a vector of bytes, starting with the LSB 5 | /// (least-significat bit) of the first element of the vector. 6 | pub struct BitIterator<'a> { 7 | object: &'a [u8], 8 | next_index: usize, 9 | end_index: usize, 10 | } 11 | 12 | impl<'a> BitIterator<'a> { 13 | /// Creates an iterator from a vector of bytes. Each byte becomes eight bits, with the least 14 | /// significant bits coming first. 15 | pub fn from_bytes(obj: &'a [u8]) -> BitIterator<'_> { 16 | BitIterator { 17 | object: obj, 18 | next_index: 0, 19 | end_index: obj.len() * U8BITS, 20 | } 21 | } 22 | 23 | /// Returns the number of ones in the binary representation of the underlying object. 24 | pub fn count_ones(&self) -> u32 { 25 | self.object.iter().fold(0, |acc, bv| acc + bv.count_ones()) 26 | } 27 | } 28 | 29 | impl<'a> Iterator for BitIterator<'a> { 30 | type Item = bool; 31 | 32 | fn next(&mut self) -> Option { 33 | if self.next_index != self.end_index { 34 | let (byte_index, bit_index) = (self.next_index / U8BITS, self.next_index % U8BITS); 35 | let bit = self.object[byte_index] >> bit_index & 0x1; 36 | self.next_index += 1; 37 | Some(bit == 0x1) 38 | } else { 39 | None 40 | } 41 | } 42 | 43 | fn size_hint(&self) -> (usize, Option) { 44 | (self.end_index, Some(self.end_index)) 45 | } 46 | } 47 | 48 | impl<'a> ExactSizeIterator for BitIterator<'a> {} 49 | 50 | #[test] 51 | fn test_iterator() { 52 | let bytes = vec![0xCA, 0xFE]; 53 | let expected_bits = vec![0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1]; 54 | 55 | for (i, bit) in BitIterator::from_bytes(&bytes).enumerate() { 56 | println!("{} == {}", bit, expected_bits[i] == 1); 57 | assert_eq!(bit, expected_bits[i] == 1); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | use std::error::Error; 2 | use std::fmt; 3 | use std::io::{self, ErrorKind}; 4 | 5 | #[derive(Debug)] 6 | pub enum SocketError { 7 | ConnectionClosed, 8 | ConnectionReset, 9 | ConnectionTimedOut, 10 | InvalidAddress, 11 | InvalidReply, 12 | NotConnected, 13 | Other(String), 14 | } 15 | 16 | impl Error for SocketError { 17 | fn description(&self) -> &str { 18 | use self::SocketError::*; 19 | match *self { 20 | ConnectionClosed => "The socket is closed", 21 | ConnectionReset => "Connection reset by remote peer", 22 | ConnectionTimedOut => "Connection timed out", 23 | InvalidAddress => "Invalid address", 24 | InvalidReply => "The remote peer sent an invalid reply", 25 | NotConnected => "The socket is not connected", 26 | Other(ref s) => s, 27 | } 28 | } 29 | } 30 | 31 | impl fmt::Display for SocketError { 32 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 33 | write!(f, "{:?}", &self) 34 | } 35 | } 36 | 37 | impl From for io::Error { 38 | fn from(error: SocketError) -> io::Error { 39 | use self::SocketError::*; 40 | let kind = match error { 41 | ConnectionClosed | NotConnected => ErrorKind::NotConnected, 42 | ConnectionReset => ErrorKind::ConnectionReset, 43 | ConnectionTimedOut => ErrorKind::TimedOut, 44 | InvalidAddress => ErrorKind::InvalidInput, 45 | InvalidReply => ErrorKind::ConnectionRefused, 46 | Other(_) => ErrorKind::Other, 47 | }; 48 | io::Error::new(kind, error.to_string()) 49 | } 50 | } 51 | 52 | #[derive(Debug)] 53 | pub enum ParseError { 54 | InvalidExtensionLength, 55 | InvalidPacketLength, 56 | InvalidPacketType(u8), 57 | UnsupportedVersion, 58 | } 59 | 60 | impl fmt::Display for ParseError { 61 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 62 | write!(f, "{:?}", &self) 63 | } 64 | } 65 | 66 | impl Error for ParseError { 67 | fn description(&self) -> &str { 68 | use self::ParseError::*; 69 | match *self { 70 | InvalidExtensionLength => "Invalid extension length (must be a non-zero multiple of 4)", 71 | InvalidPacketLength => "The packet is too small", 72 | InvalidPacketType(_) => "Invalid packet type", 73 | UnsupportedVersion => "Unsupported packet version", 74 | } 75 | } 76 | } 77 | 78 | impl From for io::Error { 79 | fn from(error: ParseError) -> io::Error { 80 | io::Error::new(ErrorKind::Other, error.to_string()) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Implementation of the [Micro Transport Protocol][spec]. 2 | //! 3 | //! This library provides both a socket interface (`UtpSocket`) and a stream interface 4 | //! (`UtpStream`). 5 | //! I recommend that you use `UtpStream`, as it implements the `Read` and `Write` 6 | //! traits we all know (and love) from `std::io`, which makes it generally easier to work with than 7 | //! `UtpSocket`. 8 | //! 9 | //! [spec]: http://www.bittorrent.org/beps/bep_0029.html 10 | //! 11 | //! # Installation 12 | //! 13 | //! Ensure your `Cargo.toml` contains: 14 | //! 15 | //! ```toml 16 | //! [dependencies] 17 | //! utp = "*" 18 | //! ``` 19 | //! 20 | //! # Examples 21 | //! 22 | //! ```no_run 23 | //! extern crate utp; 24 | //! 25 | //! use utp::UtpStream; 26 | //! use std::io::Write; 27 | //! 28 | //! fn main() { 29 | //! // Connect to an hypothetical local server running on port 8080 30 | //! let addr = "127.0.0.1:8080"; 31 | //! let mut stream = UtpStream::connect(addr).expect("Error connecting to remote peer"); 32 | //! 33 | //! // Send a string 34 | //! stream.write("Hi there!".as_bytes()).expect("Write failed"); 35 | //! 36 | //! // Close the stream 37 | //! stream.close().expect("Error closing connection"); 38 | //! } 39 | //! ``` 40 | //! 41 | //! Note that you can easily convert a socket to a stream using the `Into` trait, like so: 42 | //! 43 | //! ```no_run 44 | //! # use utp::{UtpStream, UtpSocket}; 45 | //! let socket = UtpSocket::bind("0.0.0.0:0").expect("Error binding socket"); 46 | //! let stream: UtpStream = socket.into(); 47 | //! ``` 48 | 49 | #![deny(missing_docs)] 50 | // Optional features 51 | #![cfg_attr(feature = "clippy", feature(plugin))] 52 | #![cfg_attr(feature = "clippy", plugin(clippy))] 53 | #![cfg_attr( 54 | feature = "clippy", 55 | allow( 56 | len_without_is_empty, 57 | doc_markdown, 58 | needless_return, 59 | transmute_ptr_to_ref 60 | ) 61 | )] 62 | #![cfg_attr(feature = "unstable", feature(test))] 63 | 64 | // Public API 65 | pub use crate::socket::UtpListener; 66 | pub use crate::socket::UtpSocket; 67 | pub use crate::stream::UtpStream; 68 | 69 | mod bit_iterator; 70 | mod error; 71 | mod packet; 72 | mod socket; 73 | mod stream; 74 | mod time; 75 | mod util; 76 | -------------------------------------------------------------------------------- /src/packet.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | 3 | use crate::bit_iterator::BitIterator; 4 | use crate::error::ParseError; 5 | use crate::time::{Delay, Timestamp}; 6 | use std::fmt; 7 | 8 | pub const HEADER_SIZE: usize = 20; 9 | 10 | macro_rules! u8_to_unsigned_be { 11 | ($src:ident, $start:expr, $end:expr, $t:ty) => ({ 12 | (0 .. $end - $start + 1).rev().fold(0, |acc, i| acc | $src[$start+i] as $t << (i * 8)) 13 | }) 14 | } 15 | 16 | macro_rules! make_getter { 17 | ($name:ident, $t:ty, $m:ident) => { 18 | pub fn $name(&self) -> $t { 19 | let header = unsafe { &*(self.0.as_ptr() as *const PacketHeader) }; 20 | $m::from_be(header.$name) 21 | } 22 | }; 23 | } 24 | 25 | macro_rules! make_setter { 26 | ($fn_name:ident, $field:ident, $t: ty) => { 27 | pub fn $fn_name(&mut self, new: $t) { 28 | let mut header = unsafe { &mut *(self.0.as_mut_ptr() as *mut PacketHeader) }; 29 | header.$field = new.to_be(); 30 | } 31 | }; 32 | } 33 | 34 | /// Attempt to construct `Self` through conversion. 35 | /// 36 | /// Waiting for rust-lang/rust#33417 to become stable. 37 | pub trait TryFrom: Sized { 38 | type Err; 39 | fn try_from(_: T) -> Result; 40 | } 41 | 42 | #[derive(PartialEq, Eq, Debug)] 43 | pub enum PacketType { 44 | Data, // packet carries a data payload 45 | Fin, // signals the end of a connection 46 | State, // signals acknowledgment of a packet 47 | Reset, // forcibly terminates a connection 48 | Syn, // initiates a new connection with a peer 49 | } 50 | 51 | impl TryFrom for PacketType { 52 | type Err = ParseError; 53 | fn try_from(original: u8) -> Result { 54 | match original { 55 | 0 => Ok(PacketType::Data), 56 | 1 => Ok(PacketType::Fin), 57 | 2 => Ok(PacketType::State), 58 | 3 => Ok(PacketType::Reset), 59 | 4 => Ok(PacketType::Syn), 60 | n => Err(ParseError::InvalidPacketType(n)), 61 | } 62 | } 63 | } 64 | 65 | impl From for u8 { 66 | fn from(original: PacketType) -> u8 { 67 | match original { 68 | PacketType::Data => 0, 69 | PacketType::Fin => 1, 70 | PacketType::State => 2, 71 | PacketType::Reset => 3, 72 | PacketType::Syn => 4, 73 | } 74 | } 75 | } 76 | 77 | #[derive(PartialEq, Eq, Debug, Clone, Copy)] 78 | pub enum ExtensionType { 79 | None, 80 | SelectiveAck, 81 | Unknown(u8), 82 | } 83 | 84 | impl From for ExtensionType { 85 | fn from(original: u8) -> Self { 86 | match original { 87 | 0 => ExtensionType::None, 88 | 1 => ExtensionType::SelectiveAck, 89 | n => ExtensionType::Unknown(n), 90 | } 91 | } 92 | } 93 | 94 | impl From for u8 { 95 | fn from(original: ExtensionType) -> u8 { 96 | match original { 97 | ExtensionType::None => 0, 98 | ExtensionType::SelectiveAck => 1, 99 | ExtensionType::Unknown(n) => n, 100 | } 101 | } 102 | } 103 | 104 | #[derive(Clone)] 105 | pub struct Extension<'a> { 106 | ty: ExtensionType, 107 | pub data: &'a [u8], 108 | } 109 | 110 | impl<'a> Extension<'a> { 111 | pub fn len(&self) -> usize { 112 | self.data.len() 113 | } 114 | 115 | pub fn get_type(&self) -> ExtensionType { 116 | self.ty 117 | } 118 | 119 | pub fn iter(&self) -> BitIterator<'_> { 120 | BitIterator::from_bytes(self.data) 121 | } 122 | } 123 | 124 | #[repr(C)] 125 | struct PacketHeader { 126 | type_ver: u8, // type: u4, ver: u4 127 | extension: u8, 128 | connection_id: u16, 129 | // Both timestamps are in microseconds 130 | timestamp: u32, 131 | timestamp_difference: u32, 132 | wnd_size: u32, 133 | seq_nr: u16, 134 | ack_nr: u16, 135 | } 136 | 137 | impl PacketHeader { 138 | /// Sets the type of packet to the specified type. 139 | pub fn set_type(&mut self, t: PacketType) { 140 | let version = 0x0F & self.type_ver; 141 | self.type_ver = u8::from(t) << 4 | version; 142 | } 143 | 144 | /// Returns the packet's type. 145 | pub fn get_type(&self) -> PacketType { 146 | PacketType::try_from(self.type_ver >> 4).unwrap() 147 | } 148 | 149 | /// Returns the packet's version. 150 | pub fn get_version(&self) -> u8 { 151 | self.type_ver & 0x0F 152 | } 153 | 154 | /// Returns the type of the first extension 155 | pub fn get_extension_type(&self) -> ExtensionType { 156 | self.extension.into() 157 | } 158 | } 159 | 160 | impl AsRef<[u8]> for PacketHeader { 161 | /// Returns the packet header as a slice of bytes. 162 | fn as_ref(&self) -> &[u8] { 163 | unsafe { &*(self as *const PacketHeader as *const [u8; HEADER_SIZE]) } 164 | } 165 | } 166 | 167 | impl<'a> TryFrom<&'a [u8]> for PacketHeader { 168 | type Err = ParseError; 169 | /// Reads a byte buffer and returns the corresponding packet header. 170 | /// It assumes the fields are in network (big-endian) byte order, 171 | /// preserving it. 172 | fn try_from(buf: &[u8]) -> Result { 173 | // Check length 174 | if buf.len() < HEADER_SIZE { 175 | return Err(ParseError::InvalidPacketLength); 176 | } 177 | 178 | // Check version 179 | if buf[0] & 0x0F != 1 { 180 | return Err(ParseError::UnsupportedVersion); 181 | } 182 | 183 | // Check packet type 184 | if let Err(e) = PacketType::try_from(buf[0] >> 4) { 185 | return Err(e); 186 | } 187 | 188 | Ok(PacketHeader { 189 | type_ver: buf[0], 190 | extension: buf[1], 191 | connection_id: u8_to_unsigned_be!(buf, 2, 3, u16), 192 | timestamp: u8_to_unsigned_be!(buf, 4, 7, u32), 193 | timestamp_difference: u8_to_unsigned_be!(buf, 8, 11, u32), 194 | wnd_size: u8_to_unsigned_be!(buf, 12, 15, u32), 195 | seq_nr: u8_to_unsigned_be!(buf, 16, 17, u16), 196 | ack_nr: u8_to_unsigned_be!(buf, 18, 19, u16), 197 | }) 198 | } 199 | } 200 | 201 | impl Default for PacketHeader { 202 | fn default() -> PacketHeader { 203 | PacketHeader { 204 | type_ver: u8::from(PacketType::Data) << 4 | 1, 205 | extension: 0, 206 | connection_id: 0, 207 | timestamp: 0, 208 | timestamp_difference: 0, 209 | wnd_size: 0, 210 | seq_nr: 0, 211 | ack_nr: 0, 212 | } 213 | } 214 | } 215 | 216 | pub struct Packet(Vec); 217 | 218 | impl AsRef<[u8]> for Packet { 219 | fn as_ref(&self) -> &[u8] { 220 | self.0.as_ref() 221 | } 222 | } 223 | 224 | impl Packet { 225 | /// Constructs a new, empty packet. 226 | pub fn new() -> Packet { 227 | Packet(PacketHeader::default().as_ref().to_owned()) 228 | } 229 | 230 | /// Constructs a new data packet with the given payload. 231 | pub fn with_payload(payload: &[u8]) -> Packet { 232 | let mut inner = Vec::with_capacity(HEADER_SIZE + payload.len()); 233 | let mut header = PacketHeader::default(); 234 | header.set_type(PacketType::Data); 235 | // inner.copy_from_slice(header.as_ref()); 236 | // inner.copy_from_slice(payload); 237 | inner.extend_from_slice(header.as_ref()); 238 | inner.extend_from_slice(payload); 239 | 240 | Packet(inner) 241 | } 242 | 243 | #[inline] 244 | pub fn set_type(&mut self, t: PacketType) { 245 | let header = unsafe { &mut *(self.0.as_mut_ptr() as *mut PacketHeader) }; 246 | header.set_type(t); 247 | } 248 | 249 | #[inline] 250 | pub fn get_type(&self) -> PacketType { 251 | let header = unsafe { &*(self.0.as_ptr() as *const PacketHeader) }; 252 | header.get_type() 253 | } 254 | 255 | pub fn get_version(&self) -> u8 { 256 | let header = unsafe { &*(self.0.as_ptr() as *const PacketHeader) }; 257 | header.get_version() 258 | } 259 | 260 | pub fn get_extension_type(&self) -> ExtensionType { 261 | let header = unsafe { &*(self.0.as_ptr() as *const PacketHeader) }; 262 | header.get_extension_type() 263 | } 264 | 265 | pub fn extensions(&self) -> ExtensionIterator<'_> { 266 | ExtensionIterator::new(self) 267 | } 268 | 269 | pub fn payload(&self) -> &[u8] { 270 | let mut index = HEADER_SIZE; 271 | let mut extension_type = ExtensionType::from(self.0[1]); 272 | 273 | // Consume known extensions and skip over unknown ones 274 | while index < self.0.len() && extension_type != ExtensionType::None { 275 | let len = self.0[index + 1] as usize; 276 | 277 | // Assume extension is valid because the bytes come from a (valid) Packet 278 | // ... 279 | 280 | extension_type = ExtensionType::from(self.0[index]); 281 | index += len + 2; 282 | } 283 | 284 | &self.0[index..] 285 | } 286 | 287 | pub fn timestamp(&self) -> Timestamp { 288 | let header = unsafe { &*(self.0.as_ptr() as *const PacketHeader) }; 289 | u32::from_be(header.timestamp).into() 290 | } 291 | 292 | pub fn set_timestamp(&mut self, timestamp: Timestamp) { 293 | let header = unsafe { &mut *(self.0.as_mut_ptr() as *mut PacketHeader) }; 294 | header.timestamp = u32::from(timestamp).to_be(); 295 | } 296 | 297 | pub fn timestamp_difference(&self) -> Delay { 298 | let header = unsafe { &*(self.0.as_ptr() as *const PacketHeader) }; 299 | u32::from_be(header.timestamp_difference).into() 300 | } 301 | 302 | pub fn set_timestamp_difference(&mut self, delay: Delay) { 303 | let header = unsafe { &mut *(self.0.as_mut_ptr() as *mut PacketHeader) }; 304 | header.timestamp_difference = u32::from(delay).to_be(); 305 | } 306 | 307 | make_getter!(seq_nr, u16, u16); 308 | make_getter!(ack_nr, u16, u16); 309 | make_getter!(connection_id, u16, u16); 310 | make_getter!(wnd_size, u32, u32); 311 | 312 | make_setter!(set_seq_nr, seq_nr, u16); 313 | make_setter!(set_ack_nr, ack_nr, u16); 314 | make_setter!(set_connection_id, connection_id, u16); 315 | make_setter!(set_wnd_size, wnd_size, u32); 316 | 317 | /// Sets Selective ACK field in packet header and adds appropriate data. 318 | /// 319 | /// The length of the SACK extension is expressed in bytes, which 320 | /// must be a multiple of 4 and at least 4. 321 | pub fn set_sack(&mut self, bv: Vec) { 322 | // The length of the SACK extension is expressed in bytes, which 323 | // must be a multiple of 4 and at least 4. 324 | assert!(bv.len() >= 4); 325 | assert_eq!(bv.len() % 4, 0); 326 | 327 | let mut index = HEADER_SIZE; 328 | let mut extension_type = ExtensionType::from(self.0[1]); 329 | 330 | // Set extension type in header if none is used, otherwise find and update the 331 | // "next extension type" marker in the last extension before payload 332 | if extension_type == ExtensionType::None { 333 | self.0[1] = ExtensionType::SelectiveAck.into(); 334 | } else { 335 | // Skip over all extensions until last, then modify its "next extension type" field and 336 | // add the new extension after it. 337 | 338 | // Consume known extensions and skip over unknown ones 339 | while index < self.0.len() && extension_type != ExtensionType::None { 340 | let len = self.0[index + 1] as usize; 341 | // No validity checks needed 342 | // ... 343 | 344 | extension_type = ExtensionType::from(self.0[index]); 345 | 346 | // Arrived at last extension 347 | if extension_type == ExtensionType::None { 348 | // Mark existence of an additional extension 349 | self.0[index] = ExtensionType::SelectiveAck.into(); 350 | } 351 | index += len + 2; 352 | } 353 | } 354 | 355 | // Insert the new extension into the packet's data. 356 | // The way this is currently done is potentially slower than the alternative of resizing the 357 | // underlying Vec, moving the payload forward and then writing the extension in the "new" 358 | // place before the payload. 359 | 360 | // Set the type of the following (non-existent) extension 361 | self.0.insert(index, ExtensionType::None.into()); 362 | // Set this extension's length 363 | self.0.insert(index + 1, bv.len() as u8); 364 | // Write this extension's data 365 | for (i, &value) in bv.iter().enumerate() { 366 | self.0.insert(index + 2 + i, value); 367 | } 368 | } 369 | 370 | pub fn len(&self) -> usize { 371 | self.0.len() 372 | } 373 | } 374 | 375 | impl<'a> TryFrom<&'a [u8]> for Packet { 376 | type Err = ParseError; 377 | 378 | /// Decodes a byte slice and construct the equivalent Packet. 379 | /// 380 | /// Note that this method makes no attempt to guess the payload size, saving 381 | /// all except the initial 20 bytes corresponding to the header as payload. 382 | /// It's the caller's responsibility to use an appropriately sized buffer. 383 | fn try_from(buf: &[u8]) -> Result { 384 | PacketHeader::try_from(buf) 385 | .and(check_extensions(buf)) 386 | .and(Ok(Packet(buf.to_owned()))) 387 | } 388 | } 389 | 390 | impl Clone for Packet { 391 | fn clone(&self) -> Packet { 392 | Packet(self.0.clone()) 393 | } 394 | } 395 | 396 | impl fmt::Debug for Packet { 397 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 398 | f.debug_struct("Packet") 399 | .field("type", &self.get_type()) 400 | .field("version", &self.get_version()) 401 | .field("extension", &self.get_extension_type()) 402 | .field("connection_id", &self.connection_id()) 403 | .field("timestamp", &self.timestamp()) 404 | .field("timestamp_difference", &self.timestamp_difference()) 405 | .field("wnd_size", &self.wnd_size()) 406 | .field("seq_nr", &self.seq_nr()) 407 | .field("ack_nr", &self.ack_nr()) 408 | .finish() 409 | } 410 | } 411 | 412 | pub struct ExtensionIterator<'a> { 413 | raw_bytes: &'a [u8], 414 | next_extension: ExtensionType, 415 | index: usize, 416 | } 417 | 418 | impl<'a> ExtensionIterator<'a> { 419 | fn new(packet: &'a Packet) -> Self { 420 | ExtensionIterator { 421 | raw_bytes: packet.as_ref(), 422 | next_extension: ExtensionType::from(packet.as_ref()[1]), 423 | index: HEADER_SIZE, 424 | } 425 | } 426 | } 427 | 428 | impl<'a> Iterator for ExtensionIterator<'a> { 429 | type Item = Extension<'a>; 430 | 431 | fn next(&mut self) -> Option { 432 | if self.next_extension == ExtensionType::None { 433 | None 434 | } else if self.index < self.raw_bytes.len() { 435 | let len = self.raw_bytes[self.index + 1] as usize; 436 | let extension_start = self.index + 2; 437 | let extension_end = extension_start + len; 438 | 439 | // Assume extension is valid because the bytes come from a (valid) Packet 440 | let extension = Extension { 441 | ty: self.next_extension, 442 | data: &self.raw_bytes[extension_start..extension_end], 443 | }; 444 | 445 | self.next_extension = self.raw_bytes[self.index].into(); 446 | self.index += len + 2; 447 | 448 | Some(extension) 449 | } else { 450 | None 451 | } 452 | } 453 | } 454 | 455 | /// Validate correctness of packet extensions, if any, in byte slice 456 | fn check_extensions(data: &[u8]) -> Result<(), ParseError> { 457 | if data.len() < HEADER_SIZE { 458 | return Err(ParseError::InvalidPacketLength); 459 | } 460 | 461 | let mut index = HEADER_SIZE; 462 | let mut extension_type = ExtensionType::from(data[1]); 463 | 464 | if data.len() == HEADER_SIZE && extension_type != ExtensionType::None { 465 | return Err(ParseError::InvalidExtensionLength); 466 | } 467 | 468 | // Consume known extensions and skip over unknown ones 469 | while index < data.len() && extension_type != ExtensionType::None { 470 | if data.len() < index + 2 { 471 | return Err(ParseError::InvalidPacketLength); 472 | } 473 | let len = data[index + 1] as usize; 474 | let extension_start = index + 2; 475 | let extension_end = extension_start + len; 476 | 477 | // Check validity of extension length: 478 | // - non-zero, 479 | // - multiple of 4, 480 | // - does not exceed packet length 481 | if len == 0 || len % 4 != 0 || extension_end > data.len() { 482 | return Err(ParseError::InvalidExtensionLength); 483 | } 484 | 485 | extension_type = ExtensionType::from(data[index]); 486 | index += len + 2; 487 | } 488 | // Check for pending extensions (early exit of previous loop) 489 | if extension_type != ExtensionType::None { 490 | return Err(ParseError::InvalidPacketLength); 491 | } 492 | 493 | Ok(()) 494 | } 495 | 496 | #[cfg(test)] 497 | mod tests { 498 | use crate::packet::PacketType::{Data, State}; 499 | use crate::packet::*; 500 | use crate::packet::{check_extensions, PacketHeader}; 501 | use crate::time::*; 502 | use quickcheck::{QuickCheck, TestResult}; 503 | 504 | #[test] 505 | fn test_packet_decode() { 506 | let buf = [ 507 | 0x21, 0x00, 0x41, 0xa8, 0x99, 0x2f, 0xd0, 0x2a, 0x9f, 0x4a, 0x26, 0x21, 0x00, 0x10, 508 | 0x00, 0x00, 0x3a, 0xf2, 0x6c, 0x79, 509 | ]; 510 | let packet = Packet::try_from(&buf); 511 | assert!(packet.is_ok()); 512 | let packet = packet.unwrap(); 513 | assert_eq!(packet.get_version(), 1); 514 | assert_eq!(packet.get_extension_type(), ExtensionType::None); 515 | assert_eq!(packet.get_type(), State); 516 | assert_eq!(packet.connection_id(), 16808); 517 | assert_eq!(packet.timestamp(), Timestamp(2570047530)); 518 | assert_eq!(packet.timestamp_difference(), Delay(2672436769)); 519 | assert_eq!(packet.wnd_size(), 2u32.pow(20)); 520 | assert_eq!(packet.seq_nr(), 15090); 521 | assert_eq!(packet.ack_nr(), 27769); 522 | assert_eq!(packet.len(), buf.len()); 523 | assert!(packet.payload().is_empty()); 524 | } 525 | 526 | #[test] 527 | fn test_decode_packet_with_extension() { 528 | let buf = [ 529 | 0x21, 0x01, 0x41, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 530 | 0x05, 0xdc, 0xab, 0x53, 0x3a, 0xf5, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 531 | ]; 532 | let packet = Packet::try_from(&buf); 533 | assert!(packet.is_ok()); 534 | let packet = packet.unwrap(); 535 | assert_eq!(packet.get_version(), 1); 536 | assert_eq!(packet.get_extension_type(), ExtensionType::SelectiveAck); 537 | assert_eq!(packet.get_type(), State); 538 | assert_eq!(packet.connection_id(), 16807); 539 | assert_eq!(packet.timestamp(), Timestamp(0)); 540 | assert_eq!(packet.timestamp_difference(), Delay(0)); 541 | assert_eq!(packet.wnd_size(), 1500); 542 | assert_eq!(packet.seq_nr(), 43859); 543 | assert_eq!(packet.ack_nr(), 15093); 544 | assert_eq!(packet.len(), buf.len()); 545 | assert!(packet.payload().is_empty()); 546 | let extensions: Vec> = packet.extensions().collect(); 547 | assert_eq!(extensions.len(), 1); 548 | assert_eq!(extensions[0].ty, ExtensionType::SelectiveAck); 549 | assert_eq!(extensions[0].data, &[0, 0, 0, 0]); 550 | assert_eq!(extensions[0].len(), extensions[0].data.len()); 551 | assert_eq!(extensions[0].len(), 4); 552 | // Reversible 553 | assert_eq!(packet.as_ref(), &buf); 554 | } 555 | 556 | #[test] 557 | fn test_packet_decode_with_missing_extension() { 558 | let buf = [ 559 | 0x21, 0x01, 0x41, 0xa8, 0x99, 0x2f, 0xd0, 0x2a, 0x9f, 0x4a, 0x26, 0x21, 0x00, 0x10, 560 | 0x00, 0x00, 0x3a, 0xf2, 0x6c, 0x79, 561 | ]; 562 | let packet = Packet::try_from(&buf); 563 | assert!(packet.is_err()); 564 | } 565 | 566 | #[test] 567 | fn test_packet_decode_with_malformed_extension() { 568 | let buf = [ 569 | 0x21, 0x01, 0x41, 0xa8, 0x99, 0x2f, 0xd0, 0x2a, 0x9f, 0x4a, 0x26, 0x21, 0x00, 0x10, 570 | 0x00, 0x00, 0x3a, 0xf2, 0x6c, 0x79, 0x00, 0x04, 0x00, 571 | ]; 572 | let packet = Packet::try_from(&buf); 573 | assert!(packet.is_err()); 574 | } 575 | 576 | #[test] 577 | fn test_decode_packet_with_unknown_extensions() { 578 | let buf = [ 579 | 0x21, 0x01, 0x41, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 580 | 0x05, 0xdc, 0xab, 0x53, 0x3a, 0xf5, 0xff, 0x04, 0x00, 0x00, 0x00, 581 | 0x00, // Imaginary extension 582 | 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 583 | ]; 584 | match Packet::try_from(&buf) { 585 | Ok(packet) => { 586 | assert_eq!(packet.get_version(), 1); 587 | assert_eq!(packet.get_extension_type(), ExtensionType::SelectiveAck); 588 | assert_eq!(packet.get_type(), State); 589 | assert_eq!(packet.connection_id(), 16807); 590 | assert_eq!(packet.timestamp(), Timestamp(0)); 591 | assert_eq!(packet.timestamp_difference(), Delay(0)); 592 | assert_eq!(packet.wnd_size(), 1500); 593 | assert_eq!(packet.seq_nr(), 43859); 594 | assert_eq!(packet.ack_nr(), 15093); 595 | assert!(packet.payload().is_empty()); 596 | // The invalid extension is discarded 597 | let extensions: Vec> = packet.extensions().collect(); 598 | assert_eq!(extensions.len(), 2); 599 | assert_eq!(extensions[0].ty, ExtensionType::SelectiveAck); 600 | assert_eq!(extensions[0].data, &[0, 0, 0, 0]); 601 | assert_eq!(extensions[0].len(), extensions[0].data.len()); 602 | assert_eq!(extensions[0].len(), 4); 603 | } 604 | Err(ref e) => panic!("{}", e), 605 | } 606 | } 607 | 608 | #[test] 609 | fn test_packet_set_type() { 610 | let mut packet = Packet::new(); 611 | packet.set_type(PacketType::Syn); 612 | assert_eq!(packet.get_type(), PacketType::Syn); 613 | packet.set_type(PacketType::State); 614 | assert_eq!(packet.get_type(), PacketType::State); 615 | packet.set_type(PacketType::Fin); 616 | assert_eq!(packet.get_type(), PacketType::Fin); 617 | packet.set_type(PacketType::Reset); 618 | assert_eq!(packet.get_type(), PacketType::Reset); 619 | packet.set_type(PacketType::Data); 620 | assert_eq!(packet.get_type(), PacketType::Data); 621 | } 622 | 623 | #[test] 624 | fn test_packet_set_selective_acknowledgment() { 625 | let mut packet = Packet::new(); 626 | packet.set_sack(vec![1, 2, 3, 4]); 627 | 628 | { 629 | let extensions: Vec> = packet.extensions().collect(); 630 | assert_eq!(extensions.len(), 1); 631 | assert_eq!(extensions[0].ty, ExtensionType::SelectiveAck); 632 | assert_eq!(extensions[0].data, &[1, 2, 3, 4]); 633 | assert_eq!(extensions[0].len(), extensions[0].data.len()); 634 | assert_eq!(extensions[0].len(), 4); 635 | } 636 | 637 | // Add a second sack 638 | packet.set_sack(vec![5, 6, 7, 8, 9, 10, 11, 12]); 639 | 640 | let extensions: Vec> = packet.extensions().collect(); 641 | assert_eq!(extensions.len(), 2); 642 | assert_eq!(extensions[0].ty, ExtensionType::SelectiveAck); 643 | assert_eq!(extensions[0].data, &[1, 2, 3, 4]); 644 | assert_eq!(extensions[0].len(), extensions[0].data.len()); 645 | assert_eq!(extensions[0].len(), 4); 646 | assert_eq!(extensions[1].ty, ExtensionType::SelectiveAck); 647 | assert_eq!(extensions[1].data, &[5, 6, 7, 8, 9, 10, 11, 12]); 648 | assert_eq!(extensions[1].len(), extensions[1].data.len()); 649 | assert_eq!(extensions[1].len(), 8); 650 | } 651 | 652 | #[test] 653 | fn test_packet_encode() { 654 | let payload = b"Hello\n".to_vec(); 655 | let timestamp = Timestamp(15270793); 656 | let timestamp_diff = Delay(1707040186); 657 | let (connection_id, seq_nr, ack_nr): (u16, u16, u16) = (16808, 15090, 17096); 658 | let window_size: u32 = 1048576; 659 | let mut packet = Packet::with_payload(&payload[..]); 660 | packet.set_type(Data); 661 | packet.set_timestamp(timestamp); 662 | packet.set_timestamp_difference(timestamp_diff); 663 | packet.set_connection_id(connection_id); 664 | packet.set_seq_nr(seq_nr); 665 | packet.set_ack_nr(ack_nr); 666 | packet.set_wnd_size(window_size); 667 | let buf = [ 668 | 0x01, 0x00, 0x41, 0xa8, 0x00, 0xe9, 0x03, 0x89, 0x65, 0xbf, 0x5d, 0xba, 0x00, 0x10, 669 | 0x00, 0x00, 0x3a, 0xf2, 0x42, 0xc8, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 670 | ]; 671 | 672 | assert_eq!(packet.len(), buf.len()); 673 | assert_eq!(packet.len(), HEADER_SIZE + payload.len()); 674 | assert_eq!(&packet.payload(), &payload.as_slice()); 675 | assert_eq!(packet.get_version(), 1); 676 | assert_eq!(packet.get_extension_type(), ExtensionType::None); 677 | assert_eq!(packet.get_type(), Data); 678 | assert_eq!(packet.connection_id(), connection_id); 679 | assert_eq!(packet.seq_nr(), seq_nr); 680 | assert_eq!(packet.ack_nr(), ack_nr); 681 | assert_eq!(packet.wnd_size(), window_size); 682 | assert_eq!(packet.timestamp(), timestamp); 683 | assert_eq!(packet.timestamp_difference(), timestamp_diff); 684 | assert_eq!(packet.as_ref(), buf); 685 | } 686 | 687 | #[test] 688 | fn test_packet_encode_with_payload() { 689 | let payload = b"Hello\n".to_vec(); 690 | let timestamp = Timestamp(15270793); 691 | let timestamp_diff = Delay(1707040186); 692 | let (connection_id, seq_nr, ack_nr): (u16, u16, u16) = (16808, 15090, 17096); 693 | let window_size: u32 = 1048576; 694 | let mut packet = Packet::with_payload(&payload[..]); 695 | packet.set_timestamp(timestamp); 696 | packet.set_timestamp_difference(timestamp_diff); 697 | packet.set_connection_id(connection_id); 698 | packet.set_seq_nr(seq_nr); 699 | packet.set_ack_nr(ack_nr); 700 | packet.set_wnd_size(window_size); 701 | let buf = [ 702 | 0x01, 0x00, 0x41, 0xa8, 0x00, 0xe9, 0x03, 0x89, 0x65, 0xbf, 0x5d, 0xba, 0x00, 0x10, 703 | 0x00, 0x00, 0x3a, 0xf2, 0x42, 0xc8, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 704 | ]; 705 | 706 | assert_eq!(packet.len(), buf.len()); 707 | assert_eq!(packet.len(), HEADER_SIZE + payload.len()); 708 | assert_eq!(&packet.payload(), &payload.as_slice()); 709 | assert_eq!(packet.get_version(), 1); 710 | assert_eq!(packet.get_type(), Data); 711 | assert_eq!(packet.get_extension_type(), ExtensionType::None); 712 | assert_eq!(packet.connection_id(), connection_id); 713 | assert_eq!(packet.seq_nr(), seq_nr); 714 | assert_eq!(packet.ack_nr(), ack_nr); 715 | assert_eq!(packet.wnd_size(), window_size); 716 | assert_eq!(packet.timestamp(), timestamp); 717 | assert_eq!(packet.timestamp_difference(), timestamp_diff); 718 | assert_eq!(packet.as_ref(), buf); 719 | } 720 | 721 | #[test] 722 | fn test_reversible() { 723 | let buf = [ 724 | 0x01, 0x00, 0x41, 0xa8, 0x00, 0xe9, 0x03, 0x89, 0x65, 0xbf, 0x5d, 0xba, 0x00, 0x10, 725 | 0x00, 0x00, 0x3a, 0xf2, 0x42, 0xc8, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 726 | ]; 727 | assert_eq!(&Packet::try_from(&buf).unwrap().as_ref(), &buf); 728 | } 729 | 730 | #[test] 731 | fn test_decode_evil_sequence() { 732 | let buf = [ 733 | 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 734 | ]; 735 | let packet = Packet::try_from(&buf); 736 | assert!(packet.is_err()); 737 | } 738 | 739 | #[test] 740 | fn test_decode_empty_packet() { 741 | let packet = Packet::try_from(&[]); 742 | assert!(packet.is_err()); 743 | } 744 | 745 | // Use quickcheck to simulate a malicious attacker sending malformed packets 746 | #[test] 747 | fn quicktest() { 748 | fn run(x: Vec) -> TestResult { 749 | let packet = Packet::try_from(&x); 750 | 751 | if PacketHeader::try_from(&x) 752 | .and(check_extensions(&x)) 753 | .is_err() 754 | { 755 | TestResult::from_bool(packet.is_err()) 756 | } else if let Ok(packet) = packet { 757 | TestResult::from_bool(&packet.as_ref() == &x.as_slice()) 758 | } else { 759 | TestResult::from_bool(false) 760 | } 761 | } 762 | QuickCheck::new() 763 | .tests(10000) 764 | .quickcheck(run as fn(Vec) -> TestResult) 765 | } 766 | 767 | #[test] 768 | fn extension_iterator() { 769 | let buf = [ 770 | 0x21, 0x00, 0x41, 0xa8, 0x99, 0x2f, 0xd0, 0x2a, 0x9f, 0x4a, 0x26, 0x21, 0x00, 0x10, 771 | 0x00, 0x00, 0x3a, 0xf2, 0x6c, 0x79, 772 | ]; 773 | let packet = Packet::try_from(&buf).unwrap(); 774 | assert_eq!(packet.extensions().count(), 0); 775 | 776 | let buf = [ 777 | 0x21, 0x01, 0x41, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 778 | 0x05, 0xdc, 0xab, 0x53, 0x3a, 0xf5, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 779 | ]; 780 | let packet = Packet::try_from(&buf).unwrap(); 781 | let extensions: Vec> = packet.extensions().collect(); 782 | assert_eq!(extensions.len(), 1); 783 | assert_eq!(extensions[0].ty, ExtensionType::SelectiveAck); 784 | assert_eq!(extensions[0].data, &[0, 0, 0, 0]); 785 | assert_eq!(extensions[0].len(), extensions[0].data.len()); 786 | assert_eq!(extensions[0].len(), 4); 787 | 788 | let buf = [ 789 | 0x21, 0x01, 0x41, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 790 | 0x05, 0xdc, 0xab, 0x53, 0x3a, 0xf5, 0xff, 0x04, 0x01, 0x02, 0x03, 791 | 0x04, // Imaginary extension 792 | 0x00, 0x04, 0x05, 0x06, 0x07, 0x08, 793 | ]; 794 | 795 | let packet = Packet::try_from(&buf).unwrap(); 796 | let extensions: Vec> = packet.extensions().collect(); 797 | assert_eq!(extensions.len(), 2); 798 | assert_eq!(extensions[0].ty, ExtensionType::SelectiveAck); 799 | assert_eq!(extensions[0].data, &[1, 2, 3, 4]); 800 | assert_eq!(extensions[0].len(), extensions[0].data.len()); 801 | assert_eq!(extensions[0].len(), 4); 802 | assert_eq!(extensions[1].ty, ExtensionType::Unknown(0xff)); 803 | assert_eq!(extensions[1].data, &[5, 6, 7, 8]); 804 | assert_eq!(extensions[1].len(), extensions[1].data.len()); 805 | assert_eq!(extensions[1].len(), 4); 806 | } 807 | } 808 | 809 | #[cfg(all(feature = "unstable", test))] 810 | mod bench { 811 | extern crate test; 812 | 813 | use self::test::Bencher; 814 | use packet::{Packet, TryFrom}; 815 | 816 | #[bench] 817 | fn bench_decode(b: &mut Bencher) { 818 | let buf = [ 819 | 0x21, 0x00, 0x41, 0xa8, 0x99, 0x2f, 0xd0, 0x2a, 0x9f, 0x4a, 0x26, 0x21, 0x00, 0x10, 820 | 0x00, 0x00, 0x3a, 0xf2, 0x6c, 0x79, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 821 | 0x09, 0x0a, 822 | ]; 823 | b.iter(|| { 824 | let _ = test::black_box(Packet::try_from(&buf)); 825 | }); 826 | } 827 | 828 | #[bench] 829 | fn bench_encode(b: &mut Bencher) { 830 | let packet = Packet::with_payload(&[1, 2, 3, 4, 5, 6]); 831 | b.iter(|| { 832 | let _ = test::black_box(packet.as_ref()); 833 | }); 834 | } 835 | 836 | #[bench] 837 | fn bench_extract_payload(b: &mut Bencher) { 838 | let buf = [ 839 | 0x21, 0x01, 0x41, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 840 | 0x05, 0xdc, 0xab, 0x53, 0x3a, 0xf5, 0xff, 0x04, 0x01, 0x02, 0x03, 841 | 0x04, // First extension 842 | 0x00, 0x04, 0x05, 0x06, 0x07, 0x08, // Second extension, followed by data 843 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 844 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 845 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 846 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 847 | ]; 848 | let packet = Packet::try_from(&buf).unwrap(); 849 | b.iter(|| { 850 | let _ = test::black_box(packet.payload()); 851 | }); 852 | } 853 | 854 | #[bench] 855 | fn bench_extract_extensions(b: &mut Bencher) { 856 | let buf = [ 857 | 0x21, 0x01, 0x41, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 858 | 0x05, 0xdc, 0xab, 0x53, 0x3a, 0xf5, 0xff, 0x04, 0x01, 0x02, 0x03, 859 | 0x04, // First extension 860 | 0x00, 0x04, 0x05, 0x06, 0x07, 0x08, // Second extension, followed by data 861 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 862 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 863 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 864 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 865 | ]; 866 | let packet = Packet::try_from(&buf).unwrap(); 867 | b.iter(|| { 868 | let _ = test::black_box(packet.extensions().count()); 869 | }); 870 | } 871 | } 872 | -------------------------------------------------------------------------------- /src/socket.rs: -------------------------------------------------------------------------------- 1 | use crate::error::SocketError; 2 | use crate::packet::*; 3 | use crate::time::*; 4 | use crate::util::*; 5 | use log::debug; 6 | use std::cmp::{max, min}; 7 | use std::collections::VecDeque; 8 | use std::io::{ErrorKind, Result}; 9 | use std::net::{SocketAddr, ToSocketAddrs, UdpSocket}; 10 | use std::time::{Duration, Instant}; 11 | 12 | // For simplicity's sake, let us assume no packet will ever exceed the 13 | // Ethernet maximum transfer unit of 1500 bytes. 14 | const BUF_SIZE: usize = 1500; 15 | const GAIN: f64 = 1.0; 16 | const ALLOWED_INCREASE: u32 = 1; 17 | const TARGET: f64 = 100_000.0; // 100 milliseconds 18 | const MSS: u32 = 1400; 19 | const MIN_CWND: u32 = 2; 20 | const INIT_CWND: u32 = 2; 21 | const INITIAL_CONGESTION_TIMEOUT: u64 = 1000; // one second 22 | const MIN_CONGESTION_TIMEOUT: u64 = 500; // 500 ms 23 | const MAX_CONGESTION_TIMEOUT: u64 = 60_000; // one minute 24 | const BASE_HISTORY: usize = 10; // base delays history size 25 | const MAX_SYN_RETRIES: u32 = 5; // maximum connection retries 26 | const MAX_RETRANSMISSION_RETRIES: u32 = 5; // maximum retransmission retries 27 | const WINDOW_SIZE: u32 = 1024 * 1024; // local receive window size 28 | 29 | // Maximum time (in microseconds) to wait for incoming packets when the send window is full 30 | const PRE_SEND_TIMEOUT: u32 = 500_000; 31 | 32 | // Maximum age of base delay sample (60 seconds) 33 | const MAX_BASE_DELAY_AGE: Delay = Delay(60_000_000); 34 | 35 | #[derive(PartialEq, Eq, Debug, Copy, Clone)] 36 | enum SocketState { 37 | New, 38 | Connected, 39 | SynSent, 40 | FinSent, 41 | ResetReceived, 42 | Closed, 43 | } 44 | 45 | struct DelayDifferenceSample { 46 | received_at: Timestamp, 47 | difference: Delay, 48 | } 49 | 50 | /// Returns the first valid address in a `ToSocketAddrs` iterator. 51 | fn take_address(addr: A) -> Result { 52 | addr.to_socket_addrs() 53 | .and_then(|mut it| it.next().ok_or_else(|| SocketError::InvalidAddress.into())) 54 | } 55 | 56 | /// A structure that represents a uTP (Micro Transport Protocol) connection between a local socket 57 | /// and a remote socket. 58 | /// 59 | /// The socket will be closed when the value is dropped (either explicitly or when it goes out of 60 | /// scope). 61 | /// 62 | /// The default maximum retransmission retries is 5, which translates to about 16 seconds. It can be 63 | /// changed by assigning the desired maximum retransmission retries to a socket's 64 | /// `max_retransmission_retries` field. Notice that the initial congestion timeout is 500 ms and 65 | /// doubles with each timeout. 66 | /// 67 | /// # Examples 68 | /// 69 | /// ```no_run 70 | /// use utp::UtpSocket; 71 | /// 72 | /// let mut socket = UtpSocket::bind("127.0.0.1:1234").expect("Error binding socket"); 73 | /// 74 | /// let mut buf = [0; 1000]; 75 | /// let (amt, _src) = socket.recv_from(&mut buf).expect("Error receiving"); 76 | /// 77 | /// let mut buf = &mut buf[..amt]; 78 | /// buf.reverse(); 79 | /// let _ = socket.send_to(buf).expect("Error sending"); 80 | /// 81 | /// // Close the socket. You can either call `close` on the socket, 82 | /// // explicitly drop it or just let it go out of scope. 83 | /// socket.close(); 84 | /// ``` 85 | pub struct UtpSocket { 86 | /// The wrapped UDP socket 87 | socket: UdpSocket, 88 | 89 | /// Remote peer 90 | connected_to: SocketAddr, 91 | 92 | /// Sender connection identifier 93 | sender_connection_id: u16, 94 | 95 | /// Receiver connection identifier 96 | receiver_connection_id: u16, 97 | 98 | /// Sequence number for the next packet 99 | seq_nr: u16, 100 | 101 | /// Sequence number of the latest acknowledged packet sent by the remote peer 102 | ack_nr: u16, 103 | 104 | /// Socket state 105 | state: SocketState, 106 | 107 | /// Received but not acknowledged packets 108 | incoming_buffer: Vec, 109 | 110 | /// Sent but not yet acknowledged packets 111 | send_window: Vec, 112 | 113 | /// Packets not yet sent 114 | unsent_queue: VecDeque, 115 | 116 | /// How many ACKs did the socket receive for packet with sequence number equal to `ack_nr` 117 | duplicate_ack_count: u32, 118 | 119 | /// Sequence number of the latest packet the remote peer acknowledged 120 | last_acked: u16, 121 | 122 | /// Timestamp of the latest packet the remote peer acknowledged 123 | last_acked_timestamp: Timestamp, 124 | 125 | /// Sequence number of the last packet removed from the incoming buffer 126 | last_dropped: u16, 127 | 128 | /// Round-trip time to remote peer 129 | rtt: i32, 130 | 131 | /// Variance of the round-trip time to the remote peer 132 | rtt_variance: i32, 133 | 134 | /// Data from the latest packet not yet returned in `recv_from` 135 | pending_data: Vec, 136 | 137 | /// Bytes in flight 138 | curr_window: u32, 139 | 140 | /// Window size of the remote peer 141 | remote_wnd_size: u32, 142 | 143 | /// Rolling window of packet delay to remote peer 144 | base_delays: VecDeque, 145 | 146 | /// Rolling window of the difference between sending a packet and receiving its acknowledgement 147 | current_delays: Vec, 148 | 149 | /// Difference between timestamp of the latest packet received and time of reception 150 | their_delay: Delay, 151 | 152 | /// Start of the current minute for sampling purposes 153 | last_rollover: Timestamp, 154 | 155 | /// Current congestion timeout in milliseconds 156 | congestion_timeout: u64, 157 | 158 | /// Congestion window in bytes 159 | cwnd: u32, 160 | 161 | /// Maximum retransmission retries 162 | pub max_retransmission_retries: u32, 163 | } 164 | 165 | impl UtpSocket { 166 | /// Creates a new UTP socket from the given UDP socket and the remote peer's address. 167 | /// 168 | /// The connection identifier of the resulting socket is randomly generated. 169 | fn from_raw_parts(s: UdpSocket, src: SocketAddr) -> UtpSocket { 170 | let (receiver_id, sender_id) = generate_sequential_identifiers(); 171 | 172 | UtpSocket { 173 | socket: s, 174 | connected_to: src, 175 | receiver_connection_id: receiver_id, 176 | sender_connection_id: sender_id, 177 | seq_nr: 1, 178 | ack_nr: 0, 179 | state: SocketState::New, 180 | incoming_buffer: Vec::new(), 181 | send_window: Vec::new(), 182 | unsent_queue: VecDeque::new(), 183 | duplicate_ack_count: 0, 184 | last_acked: 0, 185 | last_acked_timestamp: Timestamp::default(), 186 | last_dropped: 0, 187 | rtt: 0, 188 | rtt_variance: 0, 189 | pending_data: Vec::new(), 190 | curr_window: 0, 191 | remote_wnd_size: 0, 192 | current_delays: Vec::new(), 193 | base_delays: VecDeque::with_capacity(BASE_HISTORY), 194 | their_delay: Delay::default(), 195 | last_rollover: Timestamp::default(), 196 | congestion_timeout: INITIAL_CONGESTION_TIMEOUT, 197 | cwnd: INIT_CWND * MSS, 198 | max_retransmission_retries: MAX_RETRANSMISSION_RETRIES, 199 | } 200 | } 201 | 202 | /// Creates a new UTP socket from the given address. 203 | /// 204 | /// The address type can be any implementer of the `ToSocketAddr` trait. See its documentation 205 | /// for concrete examples. 206 | /// 207 | /// If more than one valid address is specified, only the first will be used. 208 | pub fn bind(addr: A) -> Result { 209 | take_address(addr).and_then(|a| UdpSocket::bind(a).map(|s| UtpSocket::from_raw_parts(s, a))) 210 | } 211 | 212 | /// Returns the socket address that this socket was created from. 213 | pub fn local_addr(&self) -> Result { 214 | self.socket.local_addr() 215 | } 216 | 217 | /// Returns the socket address of the remote peer of this UTP connection. 218 | pub fn peer_addr(&self) -> Result { 219 | if self.state == SocketState::Connected || self.state == SocketState::FinSent { 220 | Ok(self.connected_to) 221 | } else { 222 | Err(SocketError::NotConnected.into()) 223 | } 224 | } 225 | 226 | /// Opens a connection to a remote host by hostname or IP address. 227 | /// 228 | /// The address type can be any implementer of the `ToSocketAddr` trait. See its documentation 229 | /// for concrete examples. 230 | /// 231 | /// If more than one valid address is specified, only the first will be used. 232 | pub fn connect(other: A) -> Result { 233 | let addr = take_address(other)?; 234 | let my_addr = match addr { 235 | SocketAddr::V4(_) => "0.0.0.0:0", 236 | SocketAddr::V6(_) => "[::]:0", 237 | }; 238 | let mut socket = UtpSocket::bind(my_addr)?; 239 | socket.connected_to = addr; 240 | 241 | let mut packet = Packet::new(); 242 | packet.set_type(PacketType::Syn); 243 | packet.set_connection_id(socket.receiver_connection_id); 244 | packet.set_seq_nr(socket.seq_nr); 245 | 246 | let mut len = 0; 247 | let mut buf = [0; BUF_SIZE]; 248 | 249 | let mut syn_timeout = socket.congestion_timeout; 250 | for _ in 0..MAX_SYN_RETRIES { 251 | packet.set_timestamp(now_microseconds()); 252 | 253 | // Send packet 254 | debug!("Connecting to {}", socket.connected_to); 255 | socket 256 | .socket 257 | .send_to(packet.as_ref(), socket.connected_to)?; 258 | socket.state = SocketState::SynSent; 259 | debug!("sent {:?}", packet); 260 | 261 | // Validate response 262 | socket 263 | .socket 264 | .set_read_timeout(Some(Duration::from_millis(syn_timeout))) 265 | .expect("Error setting read timeout"); 266 | match socket.socket.recv_from(&mut buf) { 267 | Ok((read, src)) => { 268 | socket.connected_to = src; 269 | len = read; 270 | break; 271 | } 272 | Err(ref e) 273 | if (e.kind() == ErrorKind::WouldBlock || e.kind() == ErrorKind::TimedOut) => 274 | { 275 | debug!("Timed out, retrying"); 276 | syn_timeout *= 2; 277 | continue; 278 | } 279 | Err(e) => return Err(e), 280 | }; 281 | } 282 | 283 | let addr = socket.connected_to; 284 | let packet = Packet::try_from(&buf[..len])?; 285 | debug!("received {:?}", packet); 286 | socket.handle_packet(&packet, addr)?; 287 | 288 | debug!("connected to: {}", socket.connected_to); 289 | 290 | Ok(socket) 291 | } 292 | 293 | /// Gracefully closes connection to peer. 294 | /// 295 | /// This method allows both peers to receive all packets still in 296 | /// flight. 297 | pub fn close(&mut self) -> Result<()> { 298 | // Nothing to do if the socket's already closed or not connected 299 | if self.state == SocketState::Closed 300 | || self.state == SocketState::New 301 | || self.state == SocketState::SynSent 302 | { 303 | return Ok(()); 304 | } 305 | 306 | // Flush unsent and unacknowledged packets 307 | self.flush()?; 308 | 309 | let mut packet = Packet::new(); 310 | packet.set_connection_id(self.sender_connection_id); 311 | packet.set_seq_nr(self.seq_nr); 312 | packet.set_ack_nr(self.ack_nr); 313 | packet.set_timestamp(now_microseconds()); 314 | packet.set_type(PacketType::Fin); 315 | 316 | // Send FIN 317 | self.socket.send_to(packet.as_ref(), self.connected_to)?; 318 | debug!("sent {:?}", packet); 319 | self.state = SocketState::FinSent; 320 | 321 | // Receive JAKE 322 | let mut buf = [0; BUF_SIZE]; 323 | while self.state != SocketState::Closed { 324 | self.recv(&mut buf)?; 325 | } 326 | 327 | Ok(()) 328 | } 329 | 330 | /// Receives data from socket. 331 | /// 332 | /// On success, returns the number of bytes read and the sender's address. 333 | /// Returns 0 bytes read after receiving a FIN packet when the remaining 334 | /// in-flight packets are consumed. 335 | pub fn recv_from(&mut self, buf: &mut [u8]) -> Result<(usize, SocketAddr)> { 336 | let read = self.flush_incoming_buffer(buf); 337 | 338 | if read > 0 { 339 | return Ok((read, self.connected_to)); 340 | } 341 | 342 | // If the socket received a reset packet and all data has been flushed, then it can't 343 | // receive anything else 344 | if self.state == SocketState::ResetReceived { 345 | return Err(SocketError::ConnectionReset.into()); 346 | } 347 | 348 | loop { 349 | // A closed socket with no pending data can only "read" 0 new bytes. 350 | if self.state == SocketState::Closed { 351 | return Ok((0, self.connected_to)); 352 | } 353 | 354 | match self.recv(buf) { 355 | Ok((0, _src)) => continue, 356 | Ok(x) => return Ok(x), 357 | Err(e) => return Err(e), 358 | } 359 | } 360 | } 361 | 362 | fn recv(&mut self, buf: &mut [u8]) -> Result<(usize, SocketAddr)> { 363 | let mut b = [0; BUF_SIZE + HEADER_SIZE]; 364 | let start = Instant::now(); 365 | let (read, src); 366 | let mut retries = 0; 367 | 368 | // Try to receive a packet and handle timeouts 369 | loop { 370 | // Abort loop if the current try exceeds the maximum number of retransmission retries. 371 | if retries >= self.max_retransmission_retries { 372 | self.state = SocketState::Closed; 373 | return Err(SocketError::ConnectionTimedOut.into()); 374 | } 375 | 376 | let timeout = if self.state != SocketState::New { 377 | debug!("setting read timeout of {} ms", self.congestion_timeout); 378 | Some(Duration::from_millis(self.congestion_timeout)) 379 | } else { 380 | None 381 | }; 382 | 383 | self.socket 384 | .set_read_timeout(timeout) 385 | .expect("Error setting read timeout"); 386 | match self.socket.recv_from(&mut b) { 387 | Ok((r, s)) => { 388 | read = r; 389 | src = s; 390 | break; 391 | } 392 | Err(ref e) 393 | if (e.kind() == ErrorKind::WouldBlock || e.kind() == ErrorKind::TimedOut) => 394 | { 395 | debug!("recv_from timed out"); 396 | self.handle_receive_timeout()?; 397 | } 398 | Err(e) => return Err(e), 399 | }; 400 | 401 | let elapsed = start.elapsed(); 402 | let elapsed_ms = elapsed.as_secs() * 1000 + elapsed.subsec_millis() as u64; 403 | debug!("{} ms elapsed", elapsed_ms); 404 | retries += 1; 405 | } 406 | 407 | // Decode received data into a packet 408 | let packet = match Packet::try_from(&b[..read]) { 409 | Ok(packet) => packet, 410 | Err(e) => { 411 | debug!("{}", e); 412 | debug!("Ignoring invalid packet"); 413 | return Ok((0, self.connected_to)); 414 | } 415 | }; 416 | debug!("received {:?}", packet); 417 | 418 | // Process packet, including sending a reply if necessary 419 | if let Some(mut pkt) = self.handle_packet(&packet, src)? { 420 | pkt.set_wnd_size(WINDOW_SIZE); 421 | self.socket.send_to(pkt.as_ref(), src)?; 422 | debug!("sent {:?}", pkt); 423 | } 424 | 425 | // Insert data packet into the incoming buffer if it isn't a duplicate of a previously 426 | // discarded packet 427 | if packet.get_type() == PacketType::Data 428 | && packet.seq_nr().wrapping_sub(self.last_dropped) > 0 429 | { 430 | self.insert_into_buffer(packet); 431 | } 432 | 433 | // Flush incoming buffer if possible 434 | let read = self.flush_incoming_buffer(buf); 435 | 436 | Ok((read, src)) 437 | } 438 | 439 | fn handle_receive_timeout(&mut self) -> Result<()> { 440 | self.congestion_timeout *= 2; 441 | self.cwnd = MSS; 442 | 443 | // There are three possible cases here: 444 | // 445 | // - If the socket is sending and waiting for acknowledgements (the send window is 446 | // not empty), resend the first unacknowledged packet; 447 | // 448 | // - If the socket is not sending and it hasn't sent a FIN yet, then it's waiting 449 | // for incoming packets: send a fast resend request; 450 | // 451 | // - If the socket sent a FIN previously, resend it. 452 | debug!( 453 | "self.send_window: {:?}", 454 | self.send_window 455 | .iter() 456 | .map(Packet::seq_nr) 457 | .collect::>() 458 | ); 459 | 460 | if self.send_window.is_empty() { 461 | // The socket is trying to close, all sent packets were acknowledged, and it has 462 | // already sent a FIN: resend it. 463 | if self.state == SocketState::FinSent { 464 | let mut packet = Packet::new(); 465 | packet.set_connection_id(self.sender_connection_id); 466 | packet.set_seq_nr(self.seq_nr); 467 | packet.set_ack_nr(self.ack_nr); 468 | packet.set_timestamp(now_microseconds()); 469 | packet.set_type(PacketType::Fin); 470 | 471 | // Send FIN 472 | self.socket.send_to(packet.as_ref(), self.connected_to)?; 473 | debug!("resent FIN: {:?}", packet); 474 | } else if self.state != SocketState::New { 475 | // The socket is waiting for incoming packets but the remote peer is silent: 476 | // send a fast resend request. 477 | debug!("sending fast resend request"); 478 | self.send_fast_resend_request(); 479 | } 480 | } else { 481 | // The socket is sending data packets but there is no reply from the remote 482 | // peer: resend the first unacknowledged packet with the current timestamp. 483 | let packet = &mut self.send_window[0]; 484 | packet.set_timestamp(now_microseconds()); 485 | self.socket.send_to(packet.as_ref(), self.connected_to)?; 486 | debug!("resent {:?}", packet); 487 | } 488 | 489 | Ok(()) 490 | } 491 | 492 | fn prepare_reply(&self, original: &Packet, t: PacketType) -> Packet { 493 | let mut resp = Packet::new(); 494 | resp.set_type(t); 495 | let self_t_micro = now_microseconds(); 496 | let other_t_micro = original.timestamp(); 497 | let time_difference: Delay = abs_diff(self_t_micro, other_t_micro); 498 | resp.set_timestamp(self_t_micro); 499 | resp.set_timestamp_difference(time_difference); 500 | resp.set_connection_id(self.sender_connection_id); 501 | resp.set_seq_nr(self.seq_nr); 502 | resp.set_ack_nr(self.ack_nr); 503 | 504 | resp 505 | } 506 | 507 | /// Removes a packet in the incoming buffer and updates the current acknowledgement number. 508 | fn advance_incoming_buffer(&mut self) -> Option { 509 | if !self.incoming_buffer.is_empty() { 510 | let packet = self.incoming_buffer.remove(0); 511 | debug!("Removed packet from incoming buffer: {:?}", packet); 512 | self.ack_nr = packet.seq_nr(); 513 | self.last_dropped = self.ack_nr; 514 | Some(packet) 515 | } else { 516 | None 517 | } 518 | } 519 | 520 | /// Discards sequential, ordered packets in incoming buffer, starting from 521 | /// the most recently acknowledged to the most recent, as long as there are 522 | /// no missing packets. The discarded packets' payload is written to the 523 | /// slice `buf`, starting in position `start`. 524 | /// Returns the last written index. 525 | fn flush_incoming_buffer(&mut self, buf: &mut [u8]) -> usize { 526 | fn unsafe_copy(src: &[u8], dst: &mut [u8]) -> usize { 527 | let max_len = min(src.len(), dst.len()); 528 | unsafe { 529 | use std::ptr::copy; 530 | copy(src.as_ptr(), dst.as_mut_ptr(), max_len); 531 | } 532 | max_len 533 | } 534 | 535 | // Return pending data from a partially read packet 536 | if !self.pending_data.is_empty() { 537 | let flushed = unsafe_copy(&self.pending_data[..], buf); 538 | 539 | if flushed == self.pending_data.len() { 540 | self.pending_data.clear(); 541 | self.advance_incoming_buffer(); 542 | } else { 543 | self.pending_data = self.pending_data[flushed..].to_vec(); 544 | } 545 | 546 | return flushed; 547 | } 548 | 549 | if !self.incoming_buffer.is_empty() 550 | && (self.ack_nr == self.incoming_buffer[0].seq_nr() 551 | || self.ack_nr + 1 == self.incoming_buffer[0].seq_nr()) 552 | { 553 | let flushed = unsafe_copy(&self.incoming_buffer[0].payload(), buf); 554 | 555 | if flushed == self.incoming_buffer[0].payload().len() { 556 | self.advance_incoming_buffer(); 557 | } else { 558 | self.pending_data = self.incoming_buffer[0].payload()[flushed..].to_vec(); 559 | } 560 | 561 | return flushed; 562 | } 563 | 564 | 0 565 | } 566 | 567 | /// Sends data on the socket to the remote peer. On success, returns the number of bytes 568 | /// written. 569 | // 570 | // # Implementation details 571 | // 572 | // This method inserts packets into the send buffer and keeps trying to 573 | // advance the send window until an ACK corresponding to the last packet is 574 | // received. 575 | // 576 | // Note that the buffer passed to `send_to` might exceed the maximum packet 577 | // size, which will result in the data being split over several packets. 578 | pub fn send_to(&mut self, buf: &[u8]) -> Result { 579 | if self.state == SocketState::Closed { 580 | return Err(SocketError::ConnectionClosed.into()); 581 | } 582 | 583 | let total_length = buf.len(); 584 | 585 | for chunk in buf.chunks(MSS as usize - HEADER_SIZE) { 586 | let mut packet = Packet::with_payload(chunk); 587 | packet.set_seq_nr(self.seq_nr); 588 | packet.set_ack_nr(self.ack_nr); 589 | packet.set_connection_id(self.sender_connection_id); 590 | 591 | self.unsent_queue.push_back(packet); 592 | 593 | // Intentionally wrap around sequence number 594 | self.seq_nr = self.seq_nr.wrapping_add(1); 595 | } 596 | 597 | // Send every packet in the queue 598 | self.send()?; 599 | 600 | Ok(total_length) 601 | } 602 | 603 | /// Consumes acknowledgements for every pending packet. 604 | pub fn flush(&mut self) -> Result<()> { 605 | let mut buf = [0u8; BUF_SIZE]; 606 | while !self.send_window.is_empty() { 607 | debug!("packets in send window: {}", self.send_window.len()); 608 | self.recv(&mut buf)?; 609 | } 610 | 611 | Ok(()) 612 | } 613 | 614 | /// Sends every packet in the unsent packet queue. 615 | fn send(&mut self) -> Result<()> { 616 | while let Some(mut packet) = self.unsent_queue.pop_front() { 617 | self.send_packet(&mut packet)?; 618 | self.curr_window += packet.len() as u32; 619 | self.send_window.push(packet); 620 | } 621 | Ok(()) 622 | } 623 | 624 | /// Send one packet. 625 | #[inline] 626 | fn send_packet(&mut self, packet: &mut Packet) -> Result<()> { 627 | debug!("current window: {}", self.send_window.len()); 628 | let max_inflight = min(self.cwnd, self.remote_wnd_size); 629 | let max_inflight = max(MIN_CWND * MSS, max_inflight); 630 | let now = now_microseconds(); 631 | 632 | // Wait until enough in-flight packets are acknowledged for rate control purposes, but don't 633 | // wait more than 500 ms (PRE_SEND_TIMEOUT) before sending the packet. 634 | while self.curr_window >= max_inflight && now_microseconds() - now < PRE_SEND_TIMEOUT.into() 635 | { 636 | debug!("self.curr_window: {}", self.curr_window); 637 | debug!("max_inflight: {}", max_inflight); 638 | debug!("self.duplicate_ack_count: {}", self.duplicate_ack_count); 639 | debug!("now_microseconds() - now = {}", now_microseconds() - now); 640 | let mut buf = [0; BUF_SIZE]; 641 | self.recv(&mut buf)?; 642 | } 643 | debug!( 644 | "out: now_microseconds() - now = {}", 645 | now_microseconds() - now 646 | ); 647 | 648 | // Check if it still makes sense to send packet, as we might be trying to resend a lost 649 | // packet acknowledged in the receive loop above. 650 | // If there were no wrapping around of sequence numbers, we'd simply check if the packet's 651 | // sequence number is greater than `last_acked`. 652 | let distance_a = packet.seq_nr().wrapping_sub(self.last_acked); 653 | let distance_b = self.last_acked.wrapping_sub(packet.seq_nr()); 654 | if distance_a > distance_b { 655 | debug!("Packet already acknowledged, skipping..."); 656 | return Ok(()); 657 | } 658 | 659 | packet.set_timestamp(now_microseconds()); 660 | packet.set_timestamp_difference(self.their_delay); 661 | self.socket.send_to(packet.as_ref(), self.connected_to)?; 662 | debug!("sent {:?}", packet); 663 | 664 | Ok(()) 665 | } 666 | 667 | // Insert a new sample in the base delay list. 668 | // 669 | // The base delay list contains at most `BASE_HISTORY` samples, each sample is the minimum 670 | // measured over a period of a minute (MAX_BASE_DELAY_AGE). 671 | fn update_base_delay(&mut self, base_delay: Delay, now: Timestamp) { 672 | if self.base_delays.is_empty() || now - self.last_rollover > MAX_BASE_DELAY_AGE { 673 | // Update last rollover 674 | self.last_rollover = now; 675 | 676 | // Drop the oldest sample, if need be 677 | if self.base_delays.len() == BASE_HISTORY { 678 | self.base_delays.pop_front(); 679 | } 680 | 681 | // Insert new sample 682 | self.base_delays.push_back(base_delay); 683 | } else { 684 | // Replace sample for the current minute if the delay is lower 685 | let last_idx = self.base_delays.len() - 1; 686 | if base_delay < self.base_delays[last_idx] { 687 | self.base_delays[last_idx] = base_delay; 688 | } 689 | } 690 | } 691 | 692 | /// Inserts a new sample in the current delay list after removing samples older than one RTT, as 693 | /// specified in RFC6817. 694 | fn update_current_delay(&mut self, v: Delay, now: Timestamp) { 695 | // Remove samples more than one RTT old 696 | let rtt = (self.rtt as i64 * 100).into(); 697 | while !self.current_delays.is_empty() && now - self.current_delays[0].received_at > rtt { 698 | self.current_delays.remove(0); 699 | } 700 | 701 | // Insert new measurement 702 | self.current_delays.push(DelayDifferenceSample { 703 | received_at: now, 704 | difference: v, 705 | }); 706 | } 707 | 708 | fn update_congestion_timeout(&mut self, current_delay: i32) { 709 | let delta = self.rtt - current_delay; 710 | self.rtt_variance += (delta.abs() - self.rtt_variance) / 4; 711 | self.rtt += (current_delay - self.rtt) / 8; 712 | self.congestion_timeout = max( 713 | (self.rtt + self.rtt_variance * 4) as u64, 714 | MIN_CONGESTION_TIMEOUT, 715 | ); 716 | self.congestion_timeout = min(self.congestion_timeout, MAX_CONGESTION_TIMEOUT); 717 | 718 | debug!("current_delay: {}", current_delay); 719 | debug!("delta: {}", delta); 720 | debug!("self.rtt_variance: {}", self.rtt_variance); 721 | debug!("self.rtt: {}", self.rtt); 722 | debug!("self.congestion_timeout: {}", self.congestion_timeout); 723 | } 724 | 725 | /// Calculates the filtered current delay in the current window. 726 | /// 727 | /// The current delay is calculated through application of the exponential 728 | /// weighted moving average filter with smoothing factor 0.333 over the 729 | /// current delays in the current window. 730 | fn filtered_current_delay(&self) -> Delay { 731 | let input = self.current_delays.iter().map(|delay| &delay.difference); 732 | (ewma(input, 0.333) as i64).into() 733 | } 734 | 735 | /// Calculates the lowest base delay in the current window. 736 | fn min_base_delay(&self) -> Delay { 737 | self.base_delays.iter().min().cloned().unwrap_or_default() 738 | } 739 | 740 | /// Builds the selective acknowledgement extension data for usage in packets. 741 | fn build_selective_ack(&self) -> Vec { 742 | let stashed = self 743 | .incoming_buffer 744 | .iter() 745 | .filter(|pkt| pkt.seq_nr() > self.ack_nr + 1) 746 | .map(|pkt| (pkt.seq_nr() - self.ack_nr - 2) as usize) 747 | .map(|diff| (diff / 8, diff % 8)); 748 | 749 | let mut sack = Vec::new(); 750 | for (byte, bit) in stashed { 751 | // Make sure the amount of elements in the SACK vector is a 752 | // multiple of 4 and enough to represent the lost packets 753 | while byte >= sack.len() || sack.len() % 4 != 0 { 754 | sack.push(0u8); 755 | } 756 | 757 | sack[byte] |= 1 << bit; 758 | } 759 | 760 | sack 761 | } 762 | 763 | /// Sends a fast resend request to the remote peer. 764 | /// 765 | /// A fast resend request consists of sending three State packets (acknowledging the last 766 | /// received packet) in quick succession. 767 | fn send_fast_resend_request(&self) { 768 | for _ in 0..3 { 769 | let mut packet = Packet::new(); 770 | packet.set_type(PacketType::State); 771 | let self_t_micro = now_microseconds(); 772 | packet.set_timestamp(self_t_micro); 773 | packet.set_timestamp_difference(self.their_delay); 774 | packet.set_connection_id(self.sender_connection_id); 775 | packet.set_seq_nr(self.seq_nr); 776 | packet.set_ack_nr(self.ack_nr); 777 | let _ = self.socket.send_to(packet.as_ref(), self.connected_to); 778 | } 779 | } 780 | 781 | fn resend_lost_packet(&mut self, lost_packet_nr: u16) { 782 | debug!("---> resend_lost_packet({}) <---", lost_packet_nr); 783 | match self 784 | .send_window 785 | .iter() 786 | .position(|pkt| pkt.seq_nr() == lost_packet_nr) 787 | { 788 | None => debug!("Packet {} not found", lost_packet_nr), 789 | Some(position) => { 790 | debug!("self.send_window.len(): {}", self.send_window.len()); 791 | debug!("position: {}", position); 792 | let mut packet = self.send_window[position].clone(); 793 | // FIXME: Unchecked result 794 | let _ = self.send_packet(&mut packet); 795 | 796 | // We intentionally don't increase `curr_window` because otherwise a packet's length 797 | // would be counted more than once 798 | } 799 | } 800 | debug!("---> END resend_lost_packet <---"); 801 | } 802 | 803 | /// Forgets sent packets that were acknowledged by the remote peer. 804 | fn advance_send_window(&mut self) { 805 | // The reason I'm not removing the first element in a loop while its sequence number is 806 | // smaller than `last_acked` is because of wrapping sequence numbers, which would create the 807 | // sequence [..., 65534, 65535, 0, 1, ...]. If `last_acked` is smaller than the first 808 | // packet's sequence number because of wraparound (for instance, 1), no packets would be 809 | // removed, as the condition `seq_nr < last_acked` would fail immediately. 810 | // 811 | // On the other hand, I can't keep removing the first packet in a loop until its sequence 812 | // number matches `last_acked` because it might never match, and in that case no packets 813 | // should be removed. 814 | if let Some(position) = self 815 | .send_window 816 | .iter() 817 | .position(|packet| packet.seq_nr() == self.last_acked) 818 | { 819 | for _ in 0..position + 1 { 820 | let packet = self.send_window.remove(0); 821 | self.curr_window -= packet.len() as u32; 822 | } 823 | } 824 | debug!("self.curr_window: {}", self.curr_window); 825 | } 826 | 827 | /// Handles an incoming packet, updating socket state accordingly. 828 | /// 829 | /// Returns the appropriate reply packet, if needed. 830 | fn handle_packet(&mut self, packet: &Packet, src: SocketAddr) -> Result> { 831 | debug!("({:?}, {:?})", self.state, packet.get_type()); 832 | 833 | // Acknowledge only if the packet strictly follows the previous one 834 | if packet.seq_nr().wrapping_sub(self.ack_nr) == 1 { 835 | self.ack_nr = packet.seq_nr(); 836 | } 837 | 838 | // Reset connection if connection id doesn't match and this isn't a SYN 839 | if packet.get_type() != PacketType::Syn 840 | && self.state != SocketState::SynSent 841 | && !(packet.connection_id() == self.sender_connection_id 842 | || packet.connection_id() == self.receiver_connection_id) 843 | { 844 | return Ok(Some(self.prepare_reply(packet, PacketType::Reset))); 845 | } 846 | 847 | // Update remote window size 848 | self.remote_wnd_size = packet.wnd_size(); 849 | debug!("self.remote_wnd_size: {}", self.remote_wnd_size); 850 | 851 | // Update remote peer's delay between them sending the packet and us receiving it 852 | let now = now_microseconds(); 853 | self.their_delay = abs_diff(now, packet.timestamp()); 854 | debug!("self.their_delay: {}", self.their_delay); 855 | 856 | match (self.state, packet.get_type()) { 857 | (SocketState::New, PacketType::Syn) => { 858 | self.connected_to = src; 859 | self.ack_nr = packet.seq_nr(); 860 | self.seq_nr = rand::random(); 861 | self.receiver_connection_id = packet.connection_id() + 1; 862 | self.sender_connection_id = packet.connection_id(); 863 | self.state = SocketState::Connected; 864 | self.last_dropped = self.ack_nr; 865 | 866 | Ok(Some(self.prepare_reply(packet, PacketType::State))) 867 | } 868 | (_, PacketType::Syn) => Ok(Some(self.prepare_reply(packet, PacketType::Reset))), 869 | (SocketState::SynSent, PacketType::State) => { 870 | self.connected_to = src; 871 | self.ack_nr = packet.seq_nr(); 872 | self.seq_nr += 1; 873 | self.state = SocketState::Connected; 874 | self.last_acked = packet.ack_nr(); 875 | self.last_acked_timestamp = now_microseconds(); 876 | Ok(None) 877 | } 878 | (SocketState::SynSent, _) => Err(SocketError::InvalidReply.into()), 879 | (SocketState::Connected, PacketType::Data) 880 | | (SocketState::FinSent, PacketType::Data) => Ok(self.handle_data_packet(packet)), 881 | (SocketState::Connected, PacketType::State) => { 882 | self.handle_state_packet(packet); 883 | Ok(None) 884 | } 885 | (SocketState::Connected, PacketType::Fin) | (SocketState::FinSent, PacketType::Fin) => { 886 | if packet.ack_nr() < self.seq_nr { 887 | debug!("FIN received but there are missing acknowledgements for sent packets"); 888 | } 889 | let mut reply = self.prepare_reply(packet, PacketType::State); 890 | if packet.seq_nr().wrapping_sub(self.ack_nr) > 1 { 891 | debug!( 892 | "current ack_nr ({}) is behind received packet seq_nr ({})", 893 | self.ack_nr, 894 | packet.seq_nr() 895 | ); 896 | 897 | // Set SACK extension payload if the packet is not in order 898 | let sack = self.build_selective_ack(); 899 | 900 | if !sack.is_empty() { 901 | reply.set_sack(sack); 902 | } 903 | } 904 | 905 | // Give up, the remote peer might not care about our missing packets 906 | self.state = SocketState::Closed; 907 | Ok(Some(reply)) 908 | } 909 | (SocketState::Closed, PacketType::Fin) => { 910 | Ok(Some(self.prepare_reply(packet, PacketType::State))) 911 | } 912 | (SocketState::FinSent, PacketType::State) => { 913 | if packet.ack_nr() == self.seq_nr { 914 | self.state = SocketState::Closed; 915 | } else { 916 | self.handle_state_packet(packet); 917 | } 918 | Ok(None) 919 | } 920 | (_, PacketType::Reset) => { 921 | self.state = SocketState::ResetReceived; 922 | Err(SocketError::ConnectionReset.into()) 923 | } 924 | (state, ty) => { 925 | let message = format!("Unimplemented handling for ({:?},{:?})", state, ty); 926 | debug!("{}", message); 927 | Err(SocketError::Other(message).into()) 928 | } 929 | } 930 | } 931 | 932 | fn handle_data_packet(&mut self, packet: &Packet) -> Option { 933 | // If a FIN was previously sent, reply with a FIN packet acknowledging the received packet. 934 | let packet_type = if self.state == SocketState::FinSent { 935 | PacketType::Fin 936 | } else { 937 | PacketType::State 938 | }; 939 | let mut reply = self.prepare_reply(packet, packet_type); 940 | 941 | if packet.seq_nr().wrapping_sub(self.ack_nr) > 1 { 942 | debug!( 943 | "current ack_nr ({}) is behind received packet seq_nr ({})", 944 | self.ack_nr, 945 | packet.seq_nr() 946 | ); 947 | 948 | // Set SACK extension payload if the packet is not in order 949 | let sack = self.build_selective_ack(); 950 | 951 | if !sack.is_empty() { 952 | reply.set_sack(sack); 953 | } 954 | } 955 | 956 | Some(reply) 957 | } 958 | 959 | fn queuing_delay(&self) -> Delay { 960 | let filtered_current_delay = self.filtered_current_delay(); 961 | let min_base_delay = self.min_base_delay(); 962 | let queuing_delay = filtered_current_delay - min_base_delay; 963 | 964 | debug!("filtered_current_delay: {}", filtered_current_delay); 965 | debug!("min_base_delay: {}", min_base_delay); 966 | debug!("queuing_delay: {}", queuing_delay); 967 | 968 | queuing_delay 969 | } 970 | 971 | /// Calculates the new congestion window size, increasing it or decreasing it. 972 | /// 973 | /// This is the core of uTP, the [LEDBAT][ledbat_rfc] congestion algorithm. It depends on 974 | /// estimating the queuing delay between the two peers, and adjusting the congestion window 975 | /// accordingly. 976 | /// 977 | /// `off_target` is a normalized value representing the difference between the current queuing 978 | /// delay and a fixed target delay (`TARGET`). `off_target` ranges between -1.0 and 1.0. A 979 | /// positive value makes the congestion window increase, while a negative value makes the 980 | /// congestion window decrease. 981 | /// 982 | /// `bytes_newly_acked` is the number of bytes acknowledged by an inbound `State` packet. It may 983 | /// be the size of the packet explicitly acknowledged by the inbound packet (i.e., with sequence 984 | /// number equal to the inbound packet's acknowledgement number), or every packet implicitly 985 | /// acknowledged (every packet with sequence number between the previous inbound `State` 986 | /// packet's acknowledgement number and the current inbound `State` packet's acknowledgement 987 | /// number). 988 | /// 989 | ///[ledbat_rfc]: https://tools.ietf.org/html/rfc6817 990 | fn update_congestion_window(&mut self, off_target: f64, bytes_newly_acked: u32) { 991 | let flightsize = self.curr_window; 992 | 993 | let cwnd_increase = GAIN * off_target * bytes_newly_acked as f64 * MSS as f64; 994 | let cwnd_increase = cwnd_increase / self.cwnd as f64; 995 | debug!("cwnd_increase: {}", cwnd_increase); 996 | 997 | self.cwnd = (self.cwnd as f64 + cwnd_increase) as u32; 998 | let max_allowed_cwnd = flightsize + ALLOWED_INCREASE * MSS; 999 | self.cwnd = min(self.cwnd, max_allowed_cwnd); 1000 | self.cwnd = max(self.cwnd, MIN_CWND * MSS); 1001 | 1002 | debug!("cwnd: {}", self.cwnd); 1003 | debug!("max_allowed_cwnd: {}", max_allowed_cwnd); 1004 | } 1005 | 1006 | fn handle_state_packet(&mut self, packet: &Packet) { 1007 | if packet.ack_nr() == self.last_acked { 1008 | self.duplicate_ack_count += 1; 1009 | } else { 1010 | self.last_acked = packet.ack_nr(); 1011 | self.last_acked_timestamp = now_microseconds(); 1012 | self.duplicate_ack_count = 1; 1013 | } 1014 | 1015 | // Update congestion window size 1016 | if let Some(index) = self 1017 | .send_window 1018 | .iter() 1019 | .position(|p| packet.ack_nr() == p.seq_nr()) 1020 | { 1021 | // Calculate the sum of the size of every packet implicitly and explicitly acknowledged 1022 | // by the inbound packet (i.e., every packet whose sequence number precedes the inbound 1023 | // packet's acknowledgement number, plus the packet whose sequence number matches) 1024 | let bytes_newly_acked = self 1025 | .send_window 1026 | .iter() 1027 | .take(index + 1) 1028 | .fold(0, |acc, p| acc + p.len()); 1029 | 1030 | // Update base and current delay 1031 | let now = now_microseconds(); 1032 | let our_delay = now - self.send_window[index].timestamp(); 1033 | debug!("our_delay: {}", our_delay); 1034 | self.update_base_delay(our_delay, now); 1035 | self.update_current_delay(our_delay, now); 1036 | 1037 | let off_target: f64 = (TARGET - u32::from(self.queuing_delay()) as f64) / TARGET; 1038 | debug!("off_target: {}", off_target); 1039 | 1040 | self.update_congestion_window(off_target, bytes_newly_acked as u32); 1041 | 1042 | // Update congestion timeout 1043 | let rtt = u32::from(our_delay - self.queuing_delay()) / 1000; // in milliseconds 1044 | self.update_congestion_timeout(rtt as i32); 1045 | } 1046 | 1047 | let mut packet_loss_detected: bool = 1048 | !self.send_window.is_empty() && self.duplicate_ack_count == 3; 1049 | 1050 | // Process extensions, if any 1051 | for extension in packet.extensions() { 1052 | if extension.get_type() == ExtensionType::SelectiveAck { 1053 | // If three or more packets are acknowledged past the implicit missing one, 1054 | // assume it was lost. 1055 | if extension.iter().count_ones() >= 3 { 1056 | self.resend_lost_packet(packet.ack_nr() + 1); 1057 | packet_loss_detected = true; 1058 | } 1059 | 1060 | if let Some(last_seq_nr) = self.send_window.last().map(Packet::seq_nr) { 1061 | let lost_packets = extension 1062 | .iter() 1063 | .enumerate() 1064 | .filter(|&(_, received)| !received) 1065 | .map(|(idx, _)| packet.ack_nr() + 2 + idx as u16) 1066 | .take_while(|&seq_nr| seq_nr < last_seq_nr); 1067 | 1068 | for seq_nr in lost_packets { 1069 | debug!("SACK: packet {} lost", seq_nr); 1070 | self.resend_lost_packet(seq_nr); 1071 | packet_loss_detected = true; 1072 | } 1073 | } 1074 | } else { 1075 | debug!("Unknown extension {:?}, ignoring", extension.get_type()); 1076 | } 1077 | } 1078 | 1079 | // Three duplicate ACKs mean a fast resend request. Resend the first unacknowledged packet 1080 | // if the incoming packet doesn't have a SACK extension. If it does, the lost packets were 1081 | // already resent. 1082 | if !self.send_window.is_empty() 1083 | && self.duplicate_ack_count == 3 1084 | && !packet 1085 | .extensions() 1086 | .any(|ext| ext.get_type() == ExtensionType::SelectiveAck) 1087 | { 1088 | self.resend_lost_packet(packet.ack_nr() + 1); 1089 | } 1090 | 1091 | // Packet lost, halve the congestion window 1092 | if packet_loss_detected { 1093 | debug!("packet loss detected, halving congestion window"); 1094 | self.cwnd = max(self.cwnd / 2, MIN_CWND * MSS); 1095 | debug!("cwnd: {}", self.cwnd); 1096 | } 1097 | 1098 | // Success, advance send window 1099 | self.advance_send_window(); 1100 | } 1101 | 1102 | /// Inserts a packet into the socket's buffer. 1103 | /// 1104 | /// The packet is inserted in such a way that the packets in the buffer are sorted according to 1105 | /// their sequence number in ascending order. This allows storing packets that were received out 1106 | /// of order. 1107 | /// 1108 | /// Trying to insert a duplicate of a packet will silently fail. 1109 | /// it's more recent (larger timestamp). 1110 | fn insert_into_buffer(&mut self, packet: Packet) { 1111 | // Immediately push to the end if the packet's sequence number comes after the last 1112 | // packet's. 1113 | if self 1114 | .incoming_buffer 1115 | .last() 1116 | .map_or(false, |p| packet.seq_nr() > p.seq_nr()) 1117 | { 1118 | self.incoming_buffer.push(packet); 1119 | } else { 1120 | // Find index following the most recent packet before the one we wish to insert 1121 | let i = self 1122 | .incoming_buffer 1123 | .iter() 1124 | .filter(|p| p.seq_nr() < packet.seq_nr()) 1125 | .count(); 1126 | 1127 | if self 1128 | .incoming_buffer 1129 | .get(i) 1130 | .map_or(true, |p| p.seq_nr() != packet.seq_nr()) 1131 | { 1132 | self.incoming_buffer.insert(i, packet); 1133 | } 1134 | } 1135 | } 1136 | } 1137 | 1138 | impl Drop for UtpSocket { 1139 | fn drop(&mut self) { 1140 | let _ = self.close(); 1141 | } 1142 | } 1143 | 1144 | /// A structure representing a socket server. 1145 | /// 1146 | /// # Examples 1147 | /// 1148 | /// ```no_run 1149 | /// use utp::{UtpListener, UtpSocket}; 1150 | /// use std::thread; 1151 | /// 1152 | /// fn handle_client(socket: UtpSocket) { 1153 | /// // ... 1154 | /// } 1155 | /// 1156 | /// fn main() { 1157 | /// // Create a listener 1158 | /// let addr = "127.0.0.1:8080"; 1159 | /// let listener = UtpListener::bind(addr).expect("Error binding socket"); 1160 | /// 1161 | /// for connection in listener.incoming() { 1162 | /// // Spawn a new handler for each new connection 1163 | /// if let Ok((socket, _src)) = connection { 1164 | /// thread::spawn(move || handle_client(socket)); 1165 | /// } 1166 | /// } 1167 | /// } 1168 | /// ``` 1169 | pub struct UtpListener { 1170 | /// The public facing UDP socket 1171 | socket: UdpSocket, 1172 | } 1173 | 1174 | impl UtpListener { 1175 | /// Creates a new `UtpListener` bound to a specific address. 1176 | /// 1177 | /// The resulting listener is ready for accepting connections. 1178 | /// 1179 | /// The address type can be any implementer of the `ToSocketAddr` trait. See its documentation 1180 | /// for concrete examples. 1181 | /// 1182 | /// If more than one valid address is specified, only the first will be used. 1183 | pub fn bind(addr: A) -> Result { 1184 | UdpSocket::bind(addr).map(|s| UtpListener { socket: s }) 1185 | } 1186 | 1187 | /// Accepts a new incoming connection from this listener. 1188 | /// 1189 | /// This function will block the caller until a new uTP connection is established. When 1190 | /// established, the corresponding `UtpSocket` and the peer's remote address will be returned. 1191 | /// 1192 | /// Notice that the resulting `UtpSocket` is bound to a different local port than the public 1193 | /// listening port (which `UtpListener` holds). This may confuse the remote peer! 1194 | pub fn accept(&self) -> Result<(UtpSocket, SocketAddr)> { 1195 | let mut buf = [0; BUF_SIZE]; 1196 | 1197 | self.socket.recv_from(&mut buf).and_then(|(nread, src)| { 1198 | let packet = Packet::try_from(&buf[..nread])?; 1199 | 1200 | // Ignore non-SYN packets 1201 | if packet.get_type() != PacketType::Syn { 1202 | let message = format!("Expected SYN packet, got {:?} instead", packet.get_type()); 1203 | return Err(SocketError::Other(message).into()); 1204 | } 1205 | 1206 | // The address of the new socket will depend on the type of the listener. 1207 | let inner_socket = self.socket.local_addr().and_then(|addr| match addr { 1208 | SocketAddr::V4(_) => UdpSocket::bind("0.0.0.0:0"), 1209 | SocketAddr::V6(_) => UdpSocket::bind("[::]:0"), 1210 | }); 1211 | 1212 | let mut socket = inner_socket.map(|s| UtpSocket::from_raw_parts(s, src))?; 1213 | 1214 | // Establish connection with remote peer 1215 | if let Ok(Some(reply)) = socket.handle_packet(&packet, src) { 1216 | socket 1217 | .socket 1218 | .send_to(reply.as_ref(), src) 1219 | .and(Ok((socket, src))) 1220 | } else { 1221 | Err(SocketError::Other("Reached unreachable statement".to_owned()).into()) 1222 | } 1223 | }) 1224 | } 1225 | 1226 | /// Returns an iterator over the connections being received by this listener. 1227 | /// 1228 | /// The returned iterator will never return `None`. 1229 | pub fn incoming(&self) -> Incoming<'_> { 1230 | Incoming { listener: self } 1231 | } 1232 | 1233 | /// Returns the local socket address of this listener. 1234 | pub fn local_addr(&self) -> Result { 1235 | self.socket.local_addr() 1236 | } 1237 | } 1238 | 1239 | pub struct Incoming<'a> { 1240 | listener: &'a UtpListener, 1241 | } 1242 | 1243 | impl<'a> Iterator for Incoming<'a> { 1244 | type Item = Result<(UtpSocket, SocketAddr)>; 1245 | 1246 | fn next(&mut self) -> Option> { 1247 | Some(self.listener.accept()) 1248 | } 1249 | } 1250 | 1251 | #[cfg(test)] 1252 | mod test { 1253 | use crate::packet::*; 1254 | use crate::socket::{take_address, SocketState, UtpListener, UtpSocket, BUF_SIZE}; 1255 | use crate::time::now_microseconds; 1256 | use rand; 1257 | use std::io::ErrorKind; 1258 | use std::net::ToSocketAddrs; 1259 | use std::thread; 1260 | 1261 | macro_rules! iotry { 1262 | ($e:expr) => { 1263 | match $e { 1264 | Ok(e) => e, 1265 | Err(e) => panic!("{:?}", e), 1266 | } 1267 | }; 1268 | } 1269 | 1270 | fn next_test_port() -> u16 { 1271 | use std::sync::atomic::{AtomicUsize, Ordering}; 1272 | static NEXT_OFFSET: AtomicUsize = AtomicUsize::new(0); 1273 | const BASE_PORT: u16 = 9600; 1274 | BASE_PORT + NEXT_OFFSET.fetch_add(1, Ordering::Relaxed) as u16 1275 | } 1276 | 1277 | fn next_test_ip4<'a>() -> (&'a str, u16) { 1278 | ("127.0.0.1", next_test_port()) 1279 | } 1280 | 1281 | fn next_test_ip6<'a>() -> (&'a str, u16) { 1282 | ("::1", next_test_port()) 1283 | } 1284 | 1285 | #[test] 1286 | fn test_socket_ipv4() { 1287 | let server_addr = next_test_ip4(); 1288 | 1289 | let mut server = iotry!(UtpSocket::bind(server_addr)); 1290 | assert_eq!(server.state, SocketState::New); 1291 | 1292 | let child = thread::spawn(move || { 1293 | let mut client = iotry!(UtpSocket::connect(server_addr)); 1294 | assert_eq!(client.state, SocketState::Connected); 1295 | // Check proper difference in client's send connection id and receive connection id 1296 | assert_eq!( 1297 | client.sender_connection_id, 1298 | client.receiver_connection_id + 1 1299 | ); 1300 | assert_eq!( 1301 | client.connected_to, 1302 | server_addr.to_socket_addrs().unwrap().next().unwrap() 1303 | ); 1304 | iotry!(client.close()); 1305 | drop(client); 1306 | }); 1307 | 1308 | let mut buf = [0u8; BUF_SIZE]; 1309 | match server.recv_from(&mut buf) { 1310 | e => println!("{:?}", e), 1311 | } 1312 | // After establishing a new connection, the server's ids are a mirror of the client's. 1313 | assert_eq!( 1314 | server.receiver_connection_id, 1315 | server.sender_connection_id + 1 1316 | ); 1317 | 1318 | assert_eq!(server.state, SocketState::Closed); 1319 | drop(server); 1320 | 1321 | assert!(child.join().is_ok()); 1322 | } 1323 | 1324 | #[test] 1325 | fn test_socket_ipv6() { 1326 | let server_addr = next_test_ip6(); 1327 | 1328 | let mut server = iotry!(UtpSocket::bind(server_addr)); 1329 | assert_eq!(server.state, SocketState::New); 1330 | 1331 | let child = thread::spawn(move || { 1332 | let mut client = iotry!(UtpSocket::connect(server_addr)); 1333 | assert_eq!(client.state, SocketState::Connected); 1334 | // Check proper difference in client's send connection id and receive connection id 1335 | assert_eq!( 1336 | client.sender_connection_id, 1337 | client.receiver_connection_id + 1 1338 | ); 1339 | assert_eq!( 1340 | client.connected_to, 1341 | server_addr.to_socket_addrs().unwrap().next().unwrap() 1342 | ); 1343 | iotry!(client.close()); 1344 | drop(client); 1345 | }); 1346 | 1347 | let mut buf = [0u8; BUF_SIZE]; 1348 | match server.recv_from(&mut buf) { 1349 | e => println!("{:?}", e), 1350 | } 1351 | // After establishing a new connection, the server's ids are a mirror of the client's. 1352 | assert_eq!( 1353 | server.receiver_connection_id, 1354 | server.sender_connection_id + 1 1355 | ); 1356 | 1357 | assert_eq!(server.state, SocketState::Closed); 1358 | drop(server); 1359 | 1360 | assert!(child.join().is_ok()); 1361 | } 1362 | 1363 | #[test] 1364 | fn test_recvfrom_on_closed_socket() { 1365 | let server_addr = next_test_ip4(); 1366 | 1367 | let mut server = iotry!(UtpSocket::bind(server_addr)); 1368 | assert_eq!(server.state, SocketState::New); 1369 | 1370 | let child = thread::spawn(move || { 1371 | let mut client = iotry!(UtpSocket::connect(server_addr)); 1372 | assert_eq!(client.state, SocketState::Connected); 1373 | assert!(client.close().is_ok()); 1374 | }); 1375 | 1376 | // Make the server listen for incoming connections until the end of the input 1377 | let mut buf = [0u8; BUF_SIZE]; 1378 | let _resp = server.recv_from(&mut buf); 1379 | assert_eq!(server.state, SocketState::Closed); 1380 | 1381 | // Trying to receive again returns `Ok(0)` (equivalent to the old `EndOfFile`) 1382 | match server.recv_from(&mut buf) { 1383 | Ok((0, _src)) => {} 1384 | e => panic!("Expected Ok(0), got {:?}", e), 1385 | } 1386 | assert_eq!(server.state, SocketState::Closed); 1387 | 1388 | assert!(child.join().is_ok()); 1389 | } 1390 | 1391 | #[test] 1392 | fn test_sendto_on_closed_socket() { 1393 | let server_addr = next_test_ip4(); 1394 | 1395 | let mut server = iotry!(UtpSocket::bind(server_addr)); 1396 | assert_eq!(server.state, SocketState::New); 1397 | 1398 | let child = thread::spawn(move || { 1399 | let mut client = iotry!(UtpSocket::connect(server_addr)); 1400 | assert_eq!(client.state, SocketState::Connected); 1401 | iotry!(client.close()); 1402 | }); 1403 | 1404 | // Make the server listen for incoming connections 1405 | let mut buf = [0u8; BUF_SIZE]; 1406 | let (_read, _src) = iotry!(server.recv_from(&mut buf)); 1407 | assert_eq!(server.state, SocketState::Closed); 1408 | 1409 | // Trying to send to the socket after closing it raises an error 1410 | match server.send_to(&buf) { 1411 | Err(ref e) if e.kind() == ErrorKind::NotConnected => (), 1412 | v => panic!("expected {:?}, got {:?}", ErrorKind::NotConnected, v), 1413 | } 1414 | 1415 | assert!(child.join().is_ok()); 1416 | } 1417 | 1418 | #[test] 1419 | fn test_acks_on_socket() { 1420 | use std::sync::mpsc::channel; 1421 | let server_addr = next_test_ip4(); 1422 | let (tx, rx) = channel(); 1423 | 1424 | let mut server = iotry!(UtpSocket::bind(server_addr)); 1425 | 1426 | let child = thread::spawn(move || { 1427 | // Make the server listen for incoming connections 1428 | let mut buf = [0u8; BUF_SIZE]; 1429 | let _resp = server.recv(&mut buf); 1430 | tx.send(server.seq_nr).unwrap(); 1431 | 1432 | // Close the connection 1433 | iotry!(server.recv_from(&mut buf)); 1434 | 1435 | drop(server); 1436 | }); 1437 | 1438 | let mut client = iotry!(UtpSocket::connect(server_addr)); 1439 | assert_eq!(client.state, SocketState::Connected); 1440 | let sender_seq_nr = rx.recv().unwrap(); 1441 | let ack_nr = client.ack_nr; 1442 | assert_eq!(ack_nr, sender_seq_nr); 1443 | assert!(client.close().is_ok()); 1444 | 1445 | // The reply to both connect (SYN) and close (FIN) should be 1446 | // STATE packets, which don't increase the sequence number 1447 | // and, hence, the receiver's acknowledgement number. 1448 | assert_eq!(client.ack_nr, ack_nr); 1449 | drop(client); 1450 | 1451 | assert!(child.join().is_ok()); 1452 | } 1453 | 1454 | #[test] 1455 | fn test_handle_packet() { 1456 | //fn test_connection_setup() { 1457 | let initial_connection_id: u16 = rand::random(); 1458 | let sender_connection_id = initial_connection_id + 1; 1459 | let (server_addr, client_addr) = ( 1460 | next_test_ip4().to_socket_addrs().unwrap().next().unwrap(), 1461 | next_test_ip4().to_socket_addrs().unwrap().next().unwrap(), 1462 | ); 1463 | let mut socket = iotry!(UtpSocket::bind(server_addr)); 1464 | 1465 | let mut packet = Packet::new(); 1466 | packet.set_wnd_size(BUF_SIZE as u32); 1467 | packet.set_type(PacketType::Syn); 1468 | packet.set_connection_id(initial_connection_id); 1469 | 1470 | // Do we have a response? 1471 | let response = socket.handle_packet(&packet, client_addr); 1472 | assert!(response.is_ok()); 1473 | let response = response.unwrap(); 1474 | assert!(response.is_some()); 1475 | 1476 | // Is is of the correct type? 1477 | let response = response.unwrap(); 1478 | assert_eq!(response.get_type(), PacketType::State); 1479 | 1480 | // Same connection id on both ends during connection establishment 1481 | assert_eq!(response.connection_id(), packet.connection_id()); 1482 | 1483 | // Response acknowledges SYN 1484 | assert_eq!(response.ack_nr(), packet.seq_nr()); 1485 | 1486 | // No payload? 1487 | assert!(response.payload().is_empty()); 1488 | //} 1489 | 1490 | // --------------------------------- 1491 | 1492 | // fn test_connection_usage() { 1493 | let old_packet = packet; 1494 | let old_response = response; 1495 | 1496 | let mut packet = Packet::new(); 1497 | packet.set_type(PacketType::Data); 1498 | packet.set_connection_id(sender_connection_id); 1499 | packet.set_seq_nr(old_packet.seq_nr() + 1); 1500 | packet.set_ack_nr(old_response.seq_nr()); 1501 | 1502 | let response = socket.handle_packet(&packet, client_addr); 1503 | assert!(response.is_ok()); 1504 | let response = response.unwrap(); 1505 | assert!(response.is_some()); 1506 | 1507 | let response = response.unwrap(); 1508 | assert_eq!(response.get_type(), PacketType::State); 1509 | 1510 | // Sender (i.e., who the initiated connection and sent a SYN) has connection id equal to 1511 | // initial connection id + 1 1512 | // Receiver (i.e., who accepted connection) has connection id equal to initial connection id 1513 | assert_eq!(response.connection_id(), initial_connection_id); 1514 | assert_eq!(response.connection_id(), packet.connection_id() - 1); 1515 | 1516 | // Previous packets should be ack'ed 1517 | assert_eq!(response.ack_nr(), packet.seq_nr()); 1518 | 1519 | // Responses with no payload should not increase the sequence number 1520 | assert!(response.payload().is_empty()); 1521 | assert_eq!(response.seq_nr(), old_response.seq_nr()); 1522 | // } 1523 | 1524 | //fn test_connection_teardown() { 1525 | let old_packet = packet; 1526 | let old_response = response; 1527 | 1528 | let mut packet = Packet::new(); 1529 | packet.set_type(PacketType::Fin); 1530 | packet.set_connection_id(sender_connection_id); 1531 | packet.set_seq_nr(old_packet.seq_nr() + 1); 1532 | packet.set_ack_nr(old_response.seq_nr()); 1533 | 1534 | let response = socket.handle_packet(&packet, client_addr); 1535 | assert!(response.is_ok()); 1536 | let response = response.unwrap(); 1537 | assert!(response.is_some()); 1538 | 1539 | let response = response.unwrap(); 1540 | 1541 | assert_eq!(response.get_type(), PacketType::State); 1542 | 1543 | // FIN packets have no payload but the sequence number shouldn't increase 1544 | assert_eq!(packet.seq_nr(), old_packet.seq_nr() + 1); 1545 | 1546 | // Nor should the ACK packet's sequence number 1547 | assert_eq!(response.seq_nr(), old_response.seq_nr()); 1548 | 1549 | // FIN should be acknowledged 1550 | assert_eq!(response.ack_nr(), packet.seq_nr()); 1551 | 1552 | //} 1553 | } 1554 | 1555 | #[test] 1556 | fn test_response_to_keepalive_ack() { 1557 | // Boilerplate test setup 1558 | let initial_connection_id: u16 = rand::random(); 1559 | let (server_addr, client_addr) = ( 1560 | next_test_ip4().to_socket_addrs().unwrap().next().unwrap(), 1561 | next_test_ip4().to_socket_addrs().unwrap().next().unwrap(), 1562 | ); 1563 | let mut socket = iotry!(UtpSocket::bind(server_addr)); 1564 | 1565 | // Establish connection 1566 | let mut packet = Packet::new(); 1567 | packet.set_wnd_size(BUF_SIZE as u32); 1568 | packet.set_type(PacketType::Syn); 1569 | packet.set_connection_id(initial_connection_id); 1570 | 1571 | let response = socket.handle_packet(&packet, client_addr); 1572 | assert!(response.is_ok()); 1573 | let response = response.unwrap(); 1574 | assert!(response.is_some()); 1575 | let response = response.unwrap(); 1576 | assert_eq!(response.get_type(), PacketType::State); 1577 | 1578 | let old_packet = packet; 1579 | let old_response = response; 1580 | 1581 | // Now, send a keepalive packet 1582 | let mut packet = Packet::new(); 1583 | packet.set_wnd_size(BUF_SIZE as u32); 1584 | packet.set_type(PacketType::State); 1585 | packet.set_connection_id(initial_connection_id); 1586 | packet.set_seq_nr(old_packet.seq_nr() + 1); 1587 | packet.set_ack_nr(old_response.seq_nr()); 1588 | 1589 | let response = socket.handle_packet(&packet, client_addr); 1590 | assert!(response.is_ok()); 1591 | let response = response.unwrap(); 1592 | assert!(response.is_none()); 1593 | 1594 | // Send a second keepalive packet, identical to the previous one 1595 | let response = socket.handle_packet(&packet, client_addr); 1596 | assert!(response.is_ok()); 1597 | let response = response.unwrap(); 1598 | assert!(response.is_none()); 1599 | 1600 | // Mark socket as closed 1601 | socket.state = SocketState::Closed; 1602 | } 1603 | 1604 | #[test] 1605 | fn test_response_to_wrong_connection_id() { 1606 | // Boilerplate test setup 1607 | let initial_connection_id: u16 = rand::random(); 1608 | let (server_addr, client_addr) = ( 1609 | next_test_ip4().to_socket_addrs().unwrap().next().unwrap(), 1610 | next_test_ip4().to_socket_addrs().unwrap().next().unwrap(), 1611 | ); 1612 | let mut socket = iotry!(UtpSocket::bind(server_addr)); 1613 | 1614 | // Establish connection 1615 | let mut packet = Packet::new(); 1616 | packet.set_wnd_size(BUF_SIZE as u32); 1617 | packet.set_type(PacketType::Syn); 1618 | packet.set_connection_id(initial_connection_id); 1619 | 1620 | let response = socket.handle_packet(&packet, client_addr); 1621 | assert!(response.is_ok()); 1622 | let response = response.unwrap(); 1623 | assert!(response.is_some()); 1624 | assert_eq!(response.unwrap().get_type(), PacketType::State); 1625 | 1626 | // Now, disrupt connection with a packet with an incorrect connection id 1627 | let new_connection_id = initial_connection_id.wrapping_mul(2); 1628 | 1629 | let mut packet = Packet::new(); 1630 | packet.set_wnd_size(BUF_SIZE as u32); 1631 | packet.set_type(PacketType::State); 1632 | packet.set_connection_id(new_connection_id); 1633 | 1634 | let response = socket.handle_packet(&packet, client_addr); 1635 | assert!(response.is_ok()); 1636 | let response = response.unwrap(); 1637 | assert!(response.is_some()); 1638 | 1639 | let response = response.unwrap(); 1640 | assert_eq!(response.get_type(), PacketType::Reset); 1641 | assert_eq!(response.ack_nr(), packet.seq_nr()); 1642 | 1643 | // Mark socket as closed 1644 | socket.state = SocketState::Closed; 1645 | } 1646 | 1647 | #[test] 1648 | fn test_unordered_packets() { 1649 | // Boilerplate test setup 1650 | let initial_connection_id: u16 = rand::random(); 1651 | let (server_addr, client_addr) = ( 1652 | next_test_ip4().to_socket_addrs().unwrap().next().unwrap(), 1653 | next_test_ip4().to_socket_addrs().unwrap().next().unwrap(), 1654 | ); 1655 | let mut socket = iotry!(UtpSocket::bind(server_addr)); 1656 | 1657 | // Establish connection 1658 | let mut packet = Packet::new(); 1659 | packet.set_wnd_size(BUF_SIZE as u32); 1660 | packet.set_type(PacketType::Syn); 1661 | packet.set_connection_id(initial_connection_id); 1662 | 1663 | let response = socket.handle_packet(&packet, client_addr); 1664 | assert!(response.is_ok()); 1665 | let response = response.unwrap(); 1666 | assert!(response.is_some()); 1667 | let response = response.unwrap(); 1668 | assert_eq!(response.get_type(), PacketType::State); 1669 | 1670 | let old_packet = packet; 1671 | let old_response = response; 1672 | 1673 | let mut window: Vec = Vec::new(); 1674 | 1675 | // Now, send a keepalive packet 1676 | let mut packet = Packet::with_payload(&[1, 2, 3]); 1677 | packet.set_wnd_size(BUF_SIZE as u32); 1678 | packet.set_connection_id(initial_connection_id); 1679 | packet.set_seq_nr(old_packet.seq_nr() + 1); 1680 | packet.set_ack_nr(old_response.seq_nr()); 1681 | window.push(packet); 1682 | 1683 | let mut packet = Packet::with_payload(&[4, 5, 6]); 1684 | packet.set_wnd_size(BUF_SIZE as u32); 1685 | packet.set_connection_id(initial_connection_id); 1686 | packet.set_seq_nr(old_packet.seq_nr() + 2); 1687 | packet.set_ack_nr(old_response.seq_nr()); 1688 | window.push(packet); 1689 | 1690 | // Send packets in reverse order 1691 | let response = socket.handle_packet(&window[1], client_addr); 1692 | assert!(response.is_ok()); 1693 | let response = response.unwrap(); 1694 | assert!(response.is_some()); 1695 | let response = response.unwrap(); 1696 | assert!(response.ack_nr() != window[1].seq_nr()); 1697 | 1698 | let response = socket.handle_packet(&window[0], client_addr); 1699 | assert!(response.is_ok()); 1700 | let response = response.unwrap(); 1701 | assert!(response.is_some()); 1702 | 1703 | // Mark socket as closed 1704 | socket.state = SocketState::Closed; 1705 | } 1706 | 1707 | #[test] 1708 | fn test_response_to_triple_ack() { 1709 | let server_addr = next_test_ip4(); 1710 | let mut server = iotry!(UtpSocket::bind(server_addr)); 1711 | 1712 | // Fits in a packet 1713 | const LEN: usize = 1024; 1714 | let data = (0..LEN).map(|idx| idx as u8).collect::>(); 1715 | let d = data.clone(); 1716 | assert_eq!(LEN, data.len()); 1717 | 1718 | let child = thread::spawn(move || { 1719 | let mut client = iotry!(UtpSocket::connect(server_addr)); 1720 | iotry!(client.send_to(&d[..])); 1721 | iotry!(client.close()); 1722 | }); 1723 | 1724 | let mut buf = [0; BUF_SIZE]; 1725 | // Expect SYN 1726 | iotry!(server.recv(&mut buf)); 1727 | 1728 | // Receive data 1729 | let data_packet = match server.socket.recv_from(&mut buf) { 1730 | Ok((read, _src)) => iotry!(Packet::try_from(&buf[..read])), 1731 | Err(e) => panic!("{}", e), 1732 | }; 1733 | assert_eq!(data_packet.get_type(), PacketType::Data); 1734 | assert_eq!(&data_packet.payload(), &data.as_slice()); 1735 | assert_eq!(data_packet.payload().len(), data.len()); 1736 | 1737 | // Send triple ACK 1738 | let mut packet = Packet::new(); 1739 | packet.set_wnd_size(BUF_SIZE as u32); 1740 | packet.set_type(PacketType::State); 1741 | packet.set_seq_nr(server.seq_nr); 1742 | packet.set_ack_nr(data_packet.seq_nr() - 1); 1743 | packet.set_connection_id(server.sender_connection_id); 1744 | 1745 | for _ in 0..3 { 1746 | iotry!(server.socket.send_to(packet.as_ref(), server.connected_to)); 1747 | } 1748 | 1749 | // Receive data again and check that it's the same we reported as missing 1750 | let client_addr = server.connected_to; 1751 | match server.socket.recv_from(&mut buf) { 1752 | Ok((0, _)) => panic!("Received 0 bytes from socket"), 1753 | Ok((read, _src)) => { 1754 | let packet = iotry!(Packet::try_from(&buf[..read])); 1755 | assert_eq!(packet.get_type(), PacketType::Data); 1756 | assert_eq!(packet.seq_nr(), data_packet.seq_nr()); 1757 | assert_eq!(packet.payload(), data_packet.payload()); 1758 | let response = server.handle_packet(&packet, client_addr); 1759 | assert!(response.is_ok()); 1760 | let response = response.unwrap(); 1761 | assert!(response.is_some()); 1762 | let response = response.unwrap(); 1763 | iotry!(server 1764 | .socket 1765 | .send_to(response.as_ref(), server.connected_to)); 1766 | } 1767 | Err(e) => panic!("{}", e), 1768 | } 1769 | 1770 | // Receive close 1771 | iotry!(server.recv_from(&mut buf)); 1772 | 1773 | assert!(child.join().is_ok()); 1774 | } 1775 | 1776 | #[test] 1777 | fn test_socket_timeout_request() { 1778 | let (server_addr, client_addr) = ( 1779 | next_test_ip4().to_socket_addrs().unwrap().next().unwrap(), 1780 | next_test_ip4().to_socket_addrs().unwrap().next().unwrap(), 1781 | ); 1782 | 1783 | let client = iotry!(UtpSocket::bind(client_addr)); 1784 | let mut server = iotry!(UtpSocket::bind(server_addr)); 1785 | const LEN: usize = 512; 1786 | let data = (0..LEN).map(|idx| idx as u8).collect::>(); 1787 | let d = data.clone(); 1788 | 1789 | assert_eq!(server.state, SocketState::New); 1790 | assert_eq!(client.state, SocketState::New); 1791 | 1792 | // Check proper difference in client's send connection id and receive connection id 1793 | assert_eq!( 1794 | client.sender_connection_id, 1795 | client.receiver_connection_id + 1 1796 | ); 1797 | 1798 | let child = thread::spawn(move || { 1799 | let mut client = iotry!(UtpSocket::connect(server_addr)); 1800 | assert_eq!(client.state, SocketState::Connected); 1801 | assert_eq!(client.connected_to, server_addr); 1802 | iotry!(client.send_to(&d[..])); 1803 | drop(client); 1804 | }); 1805 | 1806 | let mut buf = [0u8; BUF_SIZE]; 1807 | server.recv(&mut buf).unwrap(); 1808 | // After establishing a new connection, the server's ids are a mirror of the client's. 1809 | assert_eq!( 1810 | server.receiver_connection_id, 1811 | server.sender_connection_id + 1 1812 | ); 1813 | 1814 | assert_eq!(server.state, SocketState::Connected); 1815 | 1816 | // Purposefully read from UDP socket directly and discard it, in order 1817 | // to behave as if the packet was lost and thus trigger the timeout 1818 | // handling in the *next* call to `UtpSocket.recv_from`. 1819 | iotry!(server.socket.recv_from(&mut buf)); 1820 | 1821 | // Set a much smaller than usual timeout, for quicker test completion 1822 | server.congestion_timeout = 50; 1823 | 1824 | // Now wait for the previously discarded packet 1825 | loop { 1826 | match server.recv_from(&mut buf) { 1827 | Ok((0, _)) => continue, 1828 | Ok(_) => break, 1829 | Err(e) => panic!("{}", e), 1830 | } 1831 | } 1832 | 1833 | drop(server); 1834 | 1835 | assert!(child.join().is_ok()); 1836 | } 1837 | 1838 | #[test] 1839 | fn test_sorted_buffer_insertion() { 1840 | let server_addr = next_test_ip4(); 1841 | let mut socket = iotry!(UtpSocket::bind(server_addr)); 1842 | 1843 | let mut packet = Packet::new(); 1844 | packet.set_seq_nr(1); 1845 | 1846 | assert!(socket.incoming_buffer.is_empty()); 1847 | 1848 | socket.insert_into_buffer(packet.clone()); 1849 | assert_eq!(socket.incoming_buffer.len(), 1); 1850 | 1851 | packet.set_seq_nr(2); 1852 | packet.set_timestamp(128.into()); 1853 | 1854 | socket.insert_into_buffer(packet.clone()); 1855 | assert_eq!(socket.incoming_buffer.len(), 2); 1856 | assert_eq!(socket.incoming_buffer[1].seq_nr(), 2); 1857 | assert_eq!(socket.incoming_buffer[1].timestamp(), 128.into()); 1858 | 1859 | packet.set_seq_nr(3); 1860 | packet.set_timestamp(256.into()); 1861 | 1862 | socket.insert_into_buffer(packet.clone()); 1863 | assert_eq!(socket.incoming_buffer.len(), 3); 1864 | assert_eq!(socket.incoming_buffer[2].seq_nr(), 3); 1865 | assert_eq!(socket.incoming_buffer[2].timestamp(), 256.into()); 1866 | 1867 | // Replacing a packet with a more recent version doesn't work 1868 | packet.set_seq_nr(2); 1869 | packet.set_timestamp(456.into()); 1870 | 1871 | socket.insert_into_buffer(packet.clone()); 1872 | assert_eq!(socket.incoming_buffer.len(), 3); 1873 | assert_eq!(socket.incoming_buffer[1].seq_nr(), 2); 1874 | assert_eq!(socket.incoming_buffer[1].timestamp(), 128.into()); 1875 | } 1876 | 1877 | #[test] 1878 | fn test_duplicate_packet_handling() { 1879 | let (server_addr, client_addr) = (next_test_ip4(), next_test_ip4()); 1880 | 1881 | let client = iotry!(UtpSocket::bind(client_addr)); 1882 | let mut server = iotry!(UtpSocket::bind(server_addr)); 1883 | 1884 | assert_eq!(server.state, SocketState::New); 1885 | assert_eq!(client.state, SocketState::New); 1886 | 1887 | // Check proper difference in client's send connection id and receive connection id 1888 | assert_eq!( 1889 | client.sender_connection_id, 1890 | client.receiver_connection_id + 1 1891 | ); 1892 | 1893 | let child = thread::spawn(move || { 1894 | let mut client = iotry!(UtpSocket::connect(server_addr)); 1895 | assert_eq!(client.state, SocketState::Connected); 1896 | 1897 | let mut packet = Packet::with_payload(&[1, 2, 3]); 1898 | packet.set_wnd_size(BUF_SIZE as u32); 1899 | packet.set_connection_id(client.sender_connection_id); 1900 | packet.set_seq_nr(client.seq_nr); 1901 | packet.set_ack_nr(client.ack_nr); 1902 | 1903 | // Send two copies of the packet, with different timestamps 1904 | for _ in 0..2 { 1905 | packet.set_timestamp(now_microseconds()); 1906 | iotry!(client.socket.send_to(packet.as_ref(), server_addr)); 1907 | } 1908 | client.seq_nr += 1; 1909 | 1910 | // Receive one ACK 1911 | for _ in 0..1 { 1912 | let mut buf = [0; BUF_SIZE]; 1913 | iotry!(client.socket.recv_from(&mut buf)); 1914 | } 1915 | 1916 | iotry!(client.close()); 1917 | }); 1918 | 1919 | let mut buf = [0u8; BUF_SIZE]; 1920 | iotry!(server.recv(&mut buf)); 1921 | // After establishing a new connection, the server's ids are a mirror of the client's. 1922 | assert_eq!( 1923 | server.receiver_connection_id, 1924 | server.sender_connection_id + 1 1925 | ); 1926 | 1927 | assert_eq!(server.state, SocketState::Connected); 1928 | 1929 | let expected: Vec = vec![1, 2, 3]; 1930 | let mut received: Vec = vec![]; 1931 | loop { 1932 | match server.recv_from(&mut buf) { 1933 | Ok((0, _src)) => break, 1934 | Ok((len, _src)) => received.extend(buf[..len].to_vec()), 1935 | Err(e) => panic!("{:?}", e), 1936 | } 1937 | } 1938 | assert_eq!(received.len(), expected.len()); 1939 | assert_eq!(received, expected); 1940 | 1941 | assert!(child.join().is_ok()); 1942 | } 1943 | 1944 | #[test] 1945 | fn test_correct_packet_loss() { 1946 | let server_addr = next_test_ip4(); 1947 | 1948 | let mut server = iotry!(UtpSocket::bind(server_addr)); 1949 | const LEN: usize = 1024 * 10; 1950 | let data = (0..LEN).map(|idx| idx as u8).collect::>(); 1951 | let to_send = data.clone(); 1952 | 1953 | let child = thread::spawn(move || { 1954 | let mut client = iotry!(UtpSocket::connect(server_addr)); 1955 | 1956 | // Send everything except the odd chunks 1957 | let chunks = to_send[..].chunks(BUF_SIZE); 1958 | let dst = client.connected_to; 1959 | for (index, chunk) in chunks.enumerate() { 1960 | let mut packet = Packet::with_payload(chunk); 1961 | packet.set_seq_nr(client.seq_nr); 1962 | packet.set_ack_nr(client.ack_nr); 1963 | packet.set_connection_id(client.sender_connection_id); 1964 | packet.set_timestamp(now_microseconds()); 1965 | 1966 | if index % 2 == 0 { 1967 | iotry!(client.socket.send_to(packet.as_ref(), dst)); 1968 | } 1969 | 1970 | client.curr_window += packet.len() as u32; 1971 | client.send_window.push(packet); 1972 | client.seq_nr += 1; 1973 | } 1974 | 1975 | iotry!(client.close()); 1976 | }); 1977 | 1978 | let mut buf = [0; BUF_SIZE]; 1979 | let mut received: Vec = vec![]; 1980 | loop { 1981 | match server.recv_from(&mut buf) { 1982 | Ok((0, _src)) => break, 1983 | Ok((len, _src)) => received.extend(buf[..len].to_vec()), 1984 | Err(e) => panic!("{}", e), 1985 | } 1986 | } 1987 | assert_eq!(received.len(), data.len()); 1988 | assert_eq!(received, data); 1989 | 1990 | assert!(child.join().is_ok()); 1991 | } 1992 | 1993 | #[test] 1994 | fn test_tolerance_to_small_buffers() { 1995 | let server_addr = next_test_ip4(); 1996 | let mut server = iotry!(UtpSocket::bind(server_addr)); 1997 | const LEN: usize = 1024; 1998 | let data = (0..LEN).map(|idx| idx as u8).collect::>(); 1999 | let to_send = data.clone(); 2000 | 2001 | let child = thread::spawn(move || { 2002 | let mut client = iotry!(UtpSocket::connect(server_addr)); 2003 | iotry!(client.send_to(&to_send[..])); 2004 | iotry!(client.close()); 2005 | }); 2006 | 2007 | let mut read = Vec::new(); 2008 | while server.state != SocketState::Closed { 2009 | let mut small_buffer = [0; 512]; 2010 | match server.recv_from(&mut small_buffer) { 2011 | Ok((0, _src)) => break, 2012 | Ok((len, _src)) => read.extend(small_buffer[..len].to_vec()), 2013 | Err(e) => panic!("{}", e), 2014 | } 2015 | } 2016 | 2017 | assert_eq!(read.len(), data.len()); 2018 | assert_eq!(read, data); 2019 | 2020 | assert!(child.join().is_ok()); 2021 | } 2022 | 2023 | #[test] 2024 | fn test_sequence_number_rollover() { 2025 | let (server_addr, client_addr) = (next_test_ip4(), next_test_ip4()); 2026 | 2027 | let mut server = iotry!(UtpSocket::bind(server_addr)); 2028 | 2029 | const LEN: usize = BUF_SIZE * 4; 2030 | let data = (0..LEN).map(|idx| idx as u8).collect::>(); 2031 | let to_send = data.clone(); 2032 | 2033 | let child = thread::spawn(move || { 2034 | let mut client = iotry!(UtpSocket::bind(client_addr)); 2035 | 2036 | // Advance socket's sequence number 2037 | client.seq_nr = ::std::u16::MAX - (to_send.len() / (BUF_SIZE * 2)) as u16; 2038 | 2039 | let mut client = iotry!(UtpSocket::connect(server_addr)); 2040 | // Send enough data to rollover 2041 | iotry!(client.send_to(&to_send[..])); 2042 | // Check that the sequence number did rollover 2043 | assert!(client.seq_nr < 50); 2044 | // Close connection 2045 | iotry!(client.close()); 2046 | }); 2047 | 2048 | let mut buf = [0; BUF_SIZE]; 2049 | let mut received: Vec = vec![]; 2050 | loop { 2051 | match server.recv_from(&mut buf) { 2052 | Ok((0, _src)) => break, 2053 | Ok((len, _src)) => received.extend(buf[..len].to_vec()), 2054 | Err(e) => panic!("{}", e), 2055 | } 2056 | } 2057 | assert_eq!(received.len(), data.len()); 2058 | assert_eq!(received, data); 2059 | 2060 | assert!(child.join().is_ok()); 2061 | } 2062 | 2063 | #[test] 2064 | fn test_drop_unused_socket() { 2065 | let server_addr = next_test_ip4(); 2066 | let server = iotry!(UtpSocket::bind(server_addr)); 2067 | 2068 | // Explicitly dropping socket. This test should not hang. 2069 | drop(server); 2070 | } 2071 | 2072 | #[test] 2073 | fn test_invalid_packet_on_connect() { 2074 | use std::net::UdpSocket; 2075 | let server_addr = next_test_ip4(); 2076 | let server = iotry!(UdpSocket::bind(server_addr)); 2077 | 2078 | let child = thread::spawn(move || { 2079 | let mut buf = [0; BUF_SIZE]; 2080 | match server.recv_from(&mut buf) { 2081 | Ok((_len, client_addr)) => { 2082 | iotry!(server.send_to(&[], client_addr)); 2083 | } 2084 | _ => panic!(), 2085 | } 2086 | }); 2087 | 2088 | match UtpSocket::connect(server_addr) { 2089 | Err(ref e) if e.kind() == ErrorKind::Other => (), // OK 2090 | Err(e) => panic!("Expected ErrorKind::Other, got {:?}", e), 2091 | Ok(_) => panic!("Expected Err, got Ok"), 2092 | } 2093 | 2094 | assert!(child.join().is_ok()); 2095 | } 2096 | 2097 | #[test] 2098 | fn test_receive_unexpected_reply_type_on_connect() { 2099 | use std::net::UdpSocket; 2100 | let server_addr = next_test_ip4(); 2101 | let server = iotry!(UdpSocket::bind(server_addr)); 2102 | 2103 | let child = thread::spawn(move || { 2104 | let mut buf = [0; BUF_SIZE]; 2105 | let mut packet = Packet::new(); 2106 | packet.set_type(PacketType::Data); 2107 | 2108 | match server.recv_from(&mut buf) { 2109 | Ok((_len, client_addr)) => { 2110 | iotry!(server.send_to(packet.as_ref(), client_addr)); 2111 | } 2112 | _ => panic!(), 2113 | } 2114 | }); 2115 | 2116 | match UtpSocket::connect(server_addr) { 2117 | Err(ref e) if e.kind() == ErrorKind::ConnectionRefused => (), // OK 2118 | Err(e) => panic!("Expected ErrorKind::ConnectionRefused, got {:?}", e), 2119 | Ok(_) => panic!("Expected Err, got Ok"), 2120 | } 2121 | 2122 | assert!(child.join().is_ok()); 2123 | } 2124 | 2125 | #[test] 2126 | fn test_receiving_syn_on_established_connection() { 2127 | // Establish connection 2128 | let server_addr = next_test_ip4(); 2129 | let mut server = iotry!(UtpSocket::bind(server_addr)); 2130 | 2131 | let child = thread::spawn(move || { 2132 | let mut buf = [0; BUF_SIZE]; 2133 | loop { 2134 | match server.recv_from(&mut buf) { 2135 | Ok((0, _src)) => break, 2136 | Ok(_) => (), 2137 | Err(e) => panic!("{:?}", e), 2138 | } 2139 | } 2140 | }); 2141 | 2142 | let mut client = iotry!(UtpSocket::connect(server_addr)); 2143 | let mut packet = Packet::new(); 2144 | packet.set_wnd_size(BUF_SIZE as u32); 2145 | packet.set_type(PacketType::Syn); 2146 | packet.set_connection_id(client.sender_connection_id); 2147 | packet.set_seq_nr(client.seq_nr); 2148 | packet.set_ack_nr(client.ack_nr); 2149 | iotry!(client.socket.send_to(packet.as_ref(), server_addr)); 2150 | let mut buf = [0; BUF_SIZE]; 2151 | match client.socket.recv_from(&mut buf) { 2152 | Ok((len, _src)) => { 2153 | let reply = Packet::try_from(&buf[..len]).ok().unwrap(); 2154 | assert_eq!(reply.get_type(), PacketType::Reset); 2155 | } 2156 | Err(e) => panic!("{:?}", e), 2157 | } 2158 | iotry!(client.close()); 2159 | 2160 | assert!(child.join().is_ok()); 2161 | } 2162 | 2163 | #[test] 2164 | fn test_receiving_reset_on_established_connection() { 2165 | // Establish connection 2166 | let server_addr = next_test_ip4(); 2167 | let mut server = iotry!(UtpSocket::bind(server_addr)); 2168 | 2169 | let child = thread::spawn(move || { 2170 | let client = iotry!(UtpSocket::connect(server_addr)); 2171 | let mut packet = Packet::new(); 2172 | packet.set_wnd_size(BUF_SIZE as u32); 2173 | packet.set_type(PacketType::Reset); 2174 | packet.set_connection_id(client.sender_connection_id); 2175 | packet.set_seq_nr(client.seq_nr); 2176 | packet.set_ack_nr(client.ack_nr); 2177 | iotry!(client.socket.send_to(packet.as_ref(), server_addr)); 2178 | let mut buf = [0; BUF_SIZE]; 2179 | match client.socket.recv_from(&mut buf) { 2180 | Ok((_len, _src)) => (), 2181 | Err(e) => panic!("{:?}", e), 2182 | } 2183 | }); 2184 | 2185 | let mut buf = [0; BUF_SIZE]; 2186 | loop { 2187 | match server.recv_from(&mut buf) { 2188 | Ok((0, _src)) => break, 2189 | Ok(_) => (), 2190 | Err(ref e) if e.kind() == ErrorKind::ConnectionReset => return, 2191 | Err(e) => panic!("{:?}", e), 2192 | } 2193 | } 2194 | assert!(child.join().is_ok()); 2195 | panic!("Should have received Reset"); 2196 | } 2197 | 2198 | #[cfg(not(windows))] 2199 | #[test] 2200 | fn test_premature_fin() { 2201 | let (server_addr, client_addr) = (next_test_ip4(), next_test_ip4()); 2202 | let mut server = iotry!(UtpSocket::bind(server_addr)); 2203 | 2204 | const LEN: usize = BUF_SIZE * 4; 2205 | let data = (0..LEN).map(|idx| idx as u8).collect::>(); 2206 | let to_send = data.clone(); 2207 | 2208 | let child = thread::spawn(move || { 2209 | let mut client = iotry!(UtpSocket::connect(server_addr)); 2210 | iotry!(client.send_to(&to_send[..])); 2211 | iotry!(client.close()); 2212 | }); 2213 | 2214 | let mut buf = [0; BUF_SIZE]; 2215 | 2216 | // Accept connection 2217 | iotry!(server.recv(&mut buf)); 2218 | 2219 | // Send FIN without acknowledging packets received 2220 | let mut packet = Packet::new(); 2221 | packet.set_connection_id(server.sender_connection_id); 2222 | packet.set_seq_nr(server.seq_nr); 2223 | packet.set_ack_nr(server.ack_nr); 2224 | packet.set_timestamp(now_microseconds()); 2225 | packet.set_type(PacketType::Fin); 2226 | iotry!(server.socket.send_to(packet.as_ref(), client_addr)); 2227 | 2228 | // Receive until end 2229 | let mut received: Vec = vec![]; 2230 | loop { 2231 | match server.recv_from(&mut buf) { 2232 | Ok((0, _src)) => break, 2233 | Ok((len, _src)) => received.extend(buf[..len].to_vec()), 2234 | Err(e) => panic!("{}", e), 2235 | } 2236 | } 2237 | assert_eq!(received.len(), data.len()); 2238 | assert_eq!(received, data); 2239 | 2240 | assert!(child.join().is_ok()); 2241 | } 2242 | 2243 | #[test] 2244 | fn test_base_delay_calculation() { 2245 | let minute_in_microseconds = 60 * 10i64.pow(6); 2246 | let samples = vec![ 2247 | (0, 10), 2248 | (1, 8), 2249 | (2, 12), 2250 | (3, 7), 2251 | (minute_in_microseconds + 1, 11), 2252 | (minute_in_microseconds + 2, 19), 2253 | (minute_in_microseconds + 3, 9), 2254 | ]; 2255 | let addr = next_test_ip4(); 2256 | let mut socket = UtpSocket::bind(addr).unwrap(); 2257 | 2258 | for (timestamp, delay) in samples { 2259 | socket.update_base_delay(delay.into(), ((timestamp + delay) as u32).into()); 2260 | } 2261 | 2262 | let expected = vec![7i64, 9i64] 2263 | .into_iter() 2264 | .map(Into::into) 2265 | .collect::>(); 2266 | let actual = socket.base_delays.iter().cloned().collect::>(); 2267 | assert_eq!(expected, actual); 2268 | assert_eq!( 2269 | socket.min_base_delay(), 2270 | expected.iter().min().cloned().unwrap_or_default() 2271 | ); 2272 | } 2273 | 2274 | #[test] 2275 | fn test_local_addr() { 2276 | let addr = next_test_ip4(); 2277 | let addr = addr.to_socket_addrs().unwrap().next().unwrap(); 2278 | let socket = UtpSocket::bind(addr).unwrap(); 2279 | 2280 | assert!(socket.local_addr().is_ok()); 2281 | assert_eq!(socket.local_addr().unwrap(), addr); 2282 | } 2283 | 2284 | #[test] 2285 | fn test_listener_local_addr() { 2286 | let addr = next_test_ip4(); 2287 | let addr = addr.to_socket_addrs().unwrap().next().unwrap(); 2288 | let listener = UtpListener::bind(addr).unwrap(); 2289 | 2290 | assert!(listener.local_addr().is_ok()); 2291 | assert_eq!(listener.local_addr().unwrap(), addr); 2292 | } 2293 | 2294 | #[test] 2295 | fn test_peer_addr() { 2296 | use std::sync::mpsc::channel; 2297 | let addr = next_test_ip4(); 2298 | let server_addr = addr.to_socket_addrs().unwrap().next().unwrap(); 2299 | let mut server = UtpSocket::bind(server_addr).unwrap(); 2300 | let (tx, rx) = channel(); 2301 | 2302 | // `peer_addr` should return an error because the socket isn't connected yet 2303 | assert!(server.peer_addr().is_err()); 2304 | 2305 | let child = thread::spawn(move || { 2306 | let mut client = iotry!(UtpSocket::connect(server_addr)); 2307 | let mut buf = [0; 1024]; 2308 | iotry!(tx.send(client.local_addr())); 2309 | iotry!(client.recv_from(&mut buf)); 2310 | }); 2311 | 2312 | // Wait for a connection to be established 2313 | let mut buf = [0; 1024]; 2314 | iotry!(server.recv(&mut buf)); 2315 | 2316 | // `peer_addr` should succeed and be equal to the client's address 2317 | assert!(server.peer_addr().is_ok()); 2318 | // The client is expected to be bound to "0.0.0.0", so we can only check if the port is 2319 | // correct 2320 | let client_addr = rx.recv().unwrap().unwrap(); 2321 | assert_eq!(server.peer_addr().unwrap().port(), client_addr.port()); 2322 | 2323 | // Close the connection 2324 | iotry!(server.close()); 2325 | 2326 | // `peer_addr` should now return an error because the socket is closed 2327 | assert!(server.peer_addr().is_err()); 2328 | 2329 | assert!(child.join().is_ok()); 2330 | } 2331 | 2332 | #[test] 2333 | fn test_take_address() { 2334 | // Expected successes 2335 | assert!(take_address("0.0.0.0:0").is_ok()); 2336 | assert!(take_address("[::]:0").is_ok()); 2337 | assert!(take_address(("0.0.0.0", 0)).is_ok()); 2338 | assert!(take_address(("::", 0)).is_ok()); 2339 | assert!(take_address(("1.2.3.4", 5)).is_ok()); 2340 | 2341 | // Expected failures 2342 | assert!(take_address("999.0.0.0:0").is_err()); 2343 | assert!(take_address("1.2.3.4:70000").is_err()); 2344 | assert!(take_address("").is_err()); 2345 | assert!(take_address("this is not an address").is_err()); 2346 | assert!(take_address("no.dns.resolution.com").is_err()); 2347 | } 2348 | 2349 | // Test reaction to connection loss when sending data packets 2350 | #[test] 2351 | fn test_connection_loss_data() { 2352 | let server_addr = next_test_ip4(); 2353 | let mut server = iotry!(UtpSocket::bind(server_addr)); 2354 | // Decrease timeouts for faster tests 2355 | server.congestion_timeout = 1; 2356 | let attempts = server.max_retransmission_retries; 2357 | 2358 | let child = thread::spawn(move || { 2359 | let mut client = iotry!(UtpSocket::connect(server_addr)); 2360 | iotry!(client.send_to(&[0])); 2361 | // Simulate connection loss by killing the socket. 2362 | client.state = SocketState::Closed; 2363 | let socket = client.socket.try_clone().unwrap(); 2364 | let mut buf = [0; BUF_SIZE]; 2365 | iotry!(socket.recv_from(&mut buf)); 2366 | for _ in 0..attempts { 2367 | match socket.recv_from(&mut buf) { 2368 | Ok((len, _src)) => assert_eq!( 2369 | Packet::try_from(&buf[..len]).unwrap().get_type(), 2370 | PacketType::Data 2371 | ), 2372 | Err(e) => panic!("{}", e), 2373 | } 2374 | } 2375 | }); 2376 | 2377 | // Drain incoming packets 2378 | let mut buf = [0; BUF_SIZE]; 2379 | iotry!(server.recv_from(&mut buf)); 2380 | 2381 | iotry!(server.send_to(&[0])); 2382 | 2383 | // Try to receive ACKs, time out too many times on flush, and fail with `TimedOut` 2384 | let mut buf = [0; BUF_SIZE]; 2385 | match server.recv(&mut buf) { 2386 | Err(ref e) if e.kind() == ErrorKind::TimedOut => (), 2387 | x => panic!("Expected Err(TimedOut), got {:?}", x), 2388 | } 2389 | 2390 | assert!(child.join().is_ok()); 2391 | } 2392 | 2393 | // Test reaction to connection loss when sending FIN 2394 | #[test] 2395 | fn test_connection_loss_fin() { 2396 | let server_addr = next_test_ip4(); 2397 | let mut server = iotry!(UtpSocket::bind(server_addr)); 2398 | // Decrease timeouts for faster tests 2399 | server.congestion_timeout = 1; 2400 | let attempts = server.max_retransmission_retries; 2401 | 2402 | let child = thread::spawn(move || { 2403 | let mut client = iotry!(UtpSocket::connect(server_addr)); 2404 | iotry!(client.send_to(&[0])); 2405 | // Simulate connection loss by killing the socket. 2406 | client.state = SocketState::Closed; 2407 | let socket = client.socket.try_clone().unwrap(); 2408 | let mut buf = [0; BUF_SIZE]; 2409 | iotry!(socket.recv_from(&mut buf)); 2410 | for _ in 0..attempts { 2411 | match socket.recv_from(&mut buf) { 2412 | Ok((len, _src)) => assert_eq!( 2413 | Packet::try_from(&buf[..len]).unwrap().get_type(), 2414 | PacketType::Fin 2415 | ), 2416 | Err(e) => panic!("{}", e), 2417 | } 2418 | } 2419 | }); 2420 | 2421 | // Drain incoming packets 2422 | let mut buf = [0; BUF_SIZE]; 2423 | iotry!(server.recv_from(&mut buf)); 2424 | 2425 | // Send FIN, time out too many times, and fail with `TimedOut` 2426 | match server.close() { 2427 | Err(ref e) if e.kind() == ErrorKind::TimedOut => (), 2428 | x => panic!("Expected Err(TimedOut), got {:?}", x), 2429 | } 2430 | assert!(child.join().is_ok()); 2431 | } 2432 | 2433 | // Test reaction to connection loss when waiting for data packets 2434 | #[test] 2435 | fn test_connection_loss_waiting() { 2436 | let server_addr = next_test_ip4(); 2437 | let mut server = iotry!(UtpSocket::bind(server_addr)); 2438 | // Decrease timeouts for faster tests 2439 | server.congestion_timeout = 1; 2440 | let attempts = server.max_retransmission_retries; 2441 | 2442 | let child = thread::spawn(move || { 2443 | let mut client = iotry!(UtpSocket::connect(server_addr)); 2444 | iotry!(client.send_to(&[0])); 2445 | // Simulate connection loss by killing the socket. 2446 | client.state = SocketState::Closed; 2447 | let socket = client.socket.try_clone().unwrap(); 2448 | let seq_nr = client.seq_nr; 2449 | let mut buf = [0; BUF_SIZE]; 2450 | for _ in 0..(3 * attempts) { 2451 | match socket.recv_from(&mut buf) { 2452 | Ok((len, _src)) => { 2453 | let packet = iotry!(Packet::try_from(&buf[..len])); 2454 | assert_eq!(packet.get_type(), PacketType::State); 2455 | assert_eq!(packet.ack_nr(), seq_nr - 1); 2456 | } 2457 | Err(e) => panic!("{}", e), 2458 | } 2459 | } 2460 | }); 2461 | 2462 | // Drain incoming packets 2463 | let mut buf = [0; BUF_SIZE]; 2464 | iotry!(server.recv_from(&mut buf)); 2465 | 2466 | // Try to receive data, time out too many times, and fail with `TimedOut` 2467 | let mut buf = [0; BUF_SIZE]; 2468 | match server.recv_from(&mut buf) { 2469 | Err(ref e) if e.kind() == ErrorKind::TimedOut => (), 2470 | x => panic!("Expected Err(TimedOut), got {:?}", x), 2471 | } 2472 | assert!(child.join().is_ok()); 2473 | } 2474 | } 2475 | -------------------------------------------------------------------------------- /src/stream.rs: -------------------------------------------------------------------------------- 1 | use crate::socket::UtpSocket; 2 | use std::io::{Read, Result, Write}; 3 | use std::net::{SocketAddr, ToSocketAddrs}; 4 | 5 | /// A structure that represents a uTP (Micro Transport Protocol) stream between a local socket and a 6 | /// remote socket. 7 | /// 8 | /// The connection will be closed when the value is dropped (either explicitly or when it goes out 9 | /// of scope). 10 | /// 11 | /// The default maximum retransmission retries is 5, which translates to about 16 seconds. It can be 12 | /// changed by calling `set_max_retransmission_retries`. Notice that the initial congestion timeout 13 | /// is 500 ms and doubles with each timeout. 14 | /// 15 | /// # Examples 16 | /// 17 | /// ```no_run 18 | /// use utp::UtpStream; 19 | /// use std::io::{Read, Write}; 20 | /// 21 | /// let mut stream = UtpStream::bind("127.0.0.1:1234").expect("Error binding stream"); 22 | /// let _ = stream.write(&[1]); 23 | /// let _ = stream.read(&mut [0; 1000]); 24 | /// ``` 25 | pub struct UtpStream { 26 | socket: UtpSocket, 27 | } 28 | 29 | impl UtpStream { 30 | /// Creates a uTP stream listening on the given address. 31 | /// 32 | /// The address type can be any implementer of the `ToSocketAddr` trait. See its documentation 33 | /// for concrete examples. 34 | /// 35 | /// If more than one valid address is specified, only the first will be used. 36 | pub fn bind(addr: A) -> Result { 37 | UtpSocket::bind(addr).map(|s| UtpStream { socket: s }) 38 | } 39 | 40 | /// Opens a uTP connection to a remote host by hostname or IP address. 41 | /// 42 | /// The address type can be any implementer of the `ToSocketAddr` trait. See its documentation 43 | /// for concrete examples. 44 | /// 45 | /// If more than one valid address is specified, only the first will be used. 46 | pub fn connect(dst: A) -> Result { 47 | // Port 0 means the operating system gets to choose it 48 | UtpSocket::connect(dst).map(|s| UtpStream { socket: s }) 49 | } 50 | 51 | /// Gracefully closes connection to peer. 52 | /// 53 | /// This method allows both peers to receive all packets still in 54 | /// flight. 55 | pub fn close(&mut self) -> Result<()> { 56 | self.socket.close() 57 | } 58 | 59 | /// Returns the socket address of the local half of this uTP connection. 60 | pub fn local_addr(&self) -> Result { 61 | self.socket.local_addr() 62 | } 63 | 64 | /// Changes the maximum number of retransmission retries on the underlying socket. 65 | pub fn set_max_retransmission_retries(&mut self, n: u32) { 66 | self.socket.max_retransmission_retries = n; 67 | } 68 | } 69 | 70 | impl Read for UtpStream { 71 | fn read(&mut self, buf: &mut [u8]) -> Result { 72 | self.socket.recv_from(buf).map(|(read, _src)| read) 73 | } 74 | } 75 | 76 | impl Write for UtpStream { 77 | fn write(&mut self, buf: &[u8]) -> Result { 78 | self.socket.send_to(buf) 79 | } 80 | 81 | fn flush(&mut self) -> Result<()> { 82 | self.socket.flush() 83 | } 84 | } 85 | 86 | impl From for UtpStream { 87 | fn from(socket: UtpSocket) -> Self { 88 | UtpStream { socket } 89 | } 90 | } 91 | 92 | impl AsMut for UtpStream { 93 | fn as_mut(&mut self) -> &mut UtpSocket { 94 | &mut self.socket 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/time.rs: -------------------------------------------------------------------------------- 1 | use num_traits::ToPrimitive; 2 | use std::fmt; 3 | use std::ops::Sub; 4 | use std::time; 5 | 6 | /// Return current time in microseconds since the UNIX epoch. 7 | pub fn now_microseconds() -> Timestamp { 8 | let t = time::SystemTime::now() 9 | .duration_since(time::UNIX_EPOCH) 10 | .unwrap_or_else(|e| e.duration()); 11 | (t.as_secs().wrapping_mul(1_000_000) as u32) 12 | .wrapping_add(t.subsec_micros()) 13 | .into() 14 | } 15 | 16 | #[derive(Debug, Clone, Copy, PartialOrd, PartialEq)] 17 | pub struct Timestamp(pub u32); 18 | 19 | impl Sub for Timestamp { 20 | type Output = Delay; 21 | 22 | fn sub(self, other: Timestamp) -> Delay { 23 | Delay(self.0 as i64 - other.0 as i64) 24 | } 25 | } 26 | 27 | impl Default for Timestamp { 28 | fn default() -> Timestamp { 29 | Timestamp(0) 30 | } 31 | } 32 | 33 | impl From for Timestamp { 34 | fn from(value: u32) -> Timestamp { 35 | Timestamp(value) 36 | } 37 | } 38 | 39 | impl From for u32 { 40 | fn from(value: Timestamp) -> u32 { 41 | value.0 42 | } 43 | } 44 | 45 | #[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Ord, Eq)] 46 | pub struct Delay(pub i64); 47 | 48 | impl From for Delay { 49 | fn from(value: i64) -> Delay { 50 | Delay(value) 51 | } 52 | } 53 | 54 | impl From for Delay { 55 | fn from(value: u32) -> Delay { 56 | Delay(value as i64) 57 | } 58 | } 59 | 60 | impl From for u32 { 61 | fn from(value: Delay) -> u32 { 62 | value.0 as u32 63 | } 64 | } 65 | 66 | impl Default for Delay { 67 | fn default() -> Delay { 68 | Delay(0) 69 | } 70 | } 71 | 72 | impl Sub for Delay { 73 | type Output = Delay; 74 | 75 | fn sub(self, other: Delay) -> Delay { 76 | Delay(self.0 - other.0) 77 | } 78 | } 79 | 80 | impl fmt::Display for Delay { 81 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 82 | write!(f, "Delay({})", self.0) 83 | } 84 | } 85 | 86 | impl ToPrimitive for Delay { 87 | fn to_i64(&self) -> Option { 88 | Some(self.0) 89 | } 90 | 91 | fn to_u64(&self) -> Option { 92 | Some(self.0 as u64) 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/util.rs: -------------------------------------------------------------------------------- 1 | use num_traits::ToPrimitive; 2 | use rand::{self, Rng}; 3 | use std::ops::Sub; 4 | 5 | /// Calculate the exponential weighted moving average for a vector of numbers, with a smoothing 6 | /// factor `alpha` between 0 and 1. A higher `alpha` discounts older observations faster. 7 | pub fn ewma<'a, T, I>(mut samples: I, alpha: f64) -> f64 8 | where 9 | T: ToPrimitive + 'a, 10 | I: Iterator, 11 | { 12 | let first = samples.next().map_or(0.0, |v| v.to_f64().unwrap()); 13 | samples 14 | .map(|v| v.to_f64().unwrap()) 15 | .fold(first, |avg, sample| alpha * sample + (1.0 - alpha) * avg) 16 | } 17 | 18 | /// Returns the absolute difference between two values. 19 | pub fn abs_diff, U>(a: T, b: T) -> U { 20 | if a > b { 21 | a - b 22 | } else { 23 | b - a 24 | } 25 | } 26 | 27 | /// Safely generates two sequential connection identifiers. 28 | /// 29 | /// This avoids an overflow when the generated receiver identifier is the largest 30 | /// representable value in u16 and it is incremented to yield the corresponding sender 31 | /// identifier. 32 | pub fn generate_sequential_identifiers() -> (u16, u16) { 33 | let mut rng = rand::thread_rng(); 34 | let id = rng.gen::(); 35 | if id.checked_add(1).is_some() { 36 | (id, id + 1) 37 | } else { 38 | (id - 1, id) 39 | } 40 | } 41 | 42 | #[cfg(test)] 43 | mod test { 44 | use crate::util::*; 45 | 46 | #[test] 47 | fn test_ewma_empty_vector() { 48 | let empty: Vec = vec![]; 49 | let alpha = 1.0 / 3.0; 50 | assert_eq!(ewma(empty.iter(), alpha), 0.0); 51 | } 52 | 53 | #[test] 54 | fn test_ewma_one_element() { 55 | let input = vec![1u32]; 56 | let alpha = 1.0 / 3.0; 57 | assert_eq!(ewma(input.iter(), alpha), 1.0); 58 | } 59 | 60 | #[test] 61 | fn test_exponential_smoothed_moving_average() { 62 | let input = (1u32..11).collect::>(); 63 | let alpha = 1.0 / 3.0; 64 | let expected = [ 65 | 1.0, 66 | 4.0 / 3.0, 67 | 17.0 / 9.0, 68 | 70.0 / 27.0, 69 | 275.0 / 81.0, 70 | 1036.0 / 243.0, 71 | 3773.0 / 729.0, 72 | 13378.0 / 2187.0, 73 | 46439.0 / 6561.0, 74 | 158488.0 / 19683.0, 75 | ]; 76 | assert_eq!(ewma(input.iter(), alpha), expected[expected.len() - 1]); 77 | } 78 | 79 | #[test] 80 | fn test_abs_diff() { 81 | let a = 10; 82 | let b = 5; 83 | assert_eq!(abs_diff(a, b), 5); 84 | assert_eq!(abs_diff(b, a), 5); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /tests/stream.rs: -------------------------------------------------------------------------------- 1 | use std::io::{Read, Write}; 2 | use std::thread; 3 | use utp::UtpStream; 4 | 5 | macro_rules! iotry { 6 | ($e:expr) => { 7 | match $e { 8 | Ok(e) => e, 9 | Err(e) => panic!("{}", e), 10 | } 11 | }; 12 | } 13 | 14 | fn next_test_port() -> u16 { 15 | use std::sync::atomic::{AtomicUsize, Ordering}; 16 | static NEXT_OFFSET: AtomicUsize = AtomicUsize::new(0); 17 | const BASE_PORT: u16 = 9600; 18 | BASE_PORT + NEXT_OFFSET.fetch_add(1, Ordering::Relaxed) as u16 19 | } 20 | 21 | fn next_test_ip4<'a>() -> (&'a str, u16) { 22 | ("127.0.0.1", next_test_port()) 23 | } 24 | 25 | fn next_test_ip6<'a>() -> (&'a str, u16) { 26 | ("::1", next_test_port()) 27 | } 28 | 29 | #[test] 30 | fn test_stream_open_and_close() { 31 | let server_addr = next_test_ip4(); 32 | let mut server = iotry!(UtpStream::bind(server_addr)); 33 | 34 | let child = thread::spawn(move || { 35 | let mut client = iotry!(UtpStream::connect(server_addr)); 36 | iotry!(client.close()); 37 | drop(client); 38 | }); 39 | 40 | let mut received = vec![]; 41 | iotry!(server.read_to_end(&mut received)); 42 | iotry!(server.close()); 43 | assert!(child.join().is_ok()); 44 | } 45 | 46 | #[test] 47 | fn test_stream_open_and_close_ipv6() { 48 | let server_addr = next_test_ip6(); 49 | let mut server = iotry!(UtpStream::bind(server_addr)); 50 | 51 | let child = thread::spawn(move || { 52 | let mut client = iotry!(UtpStream::connect(server_addr)); 53 | iotry!(client.close()); 54 | drop(client); 55 | }); 56 | 57 | let mut received = vec![]; 58 | iotry!(server.read_to_end(&mut received)); 59 | iotry!(server.close()); 60 | assert!(child.join().is_ok()); 61 | } 62 | 63 | #[test] 64 | fn test_stream_small_data() { 65 | // Fits in a packet 66 | const LEN: usize = 1024; 67 | let data: Vec = (0..LEN).map(|idx| idx as u8).collect(); 68 | assert_eq!(LEN, data.len()); 69 | 70 | let d = data.clone(); 71 | let server_addr = next_test_ip4(); 72 | let mut server = iotry!(UtpStream::bind(server_addr)); 73 | 74 | let child = thread::spawn(move || { 75 | let mut client = iotry!(UtpStream::connect(server_addr)); 76 | iotry!(client.write(&d[..])); 77 | iotry!(client.close()); 78 | }); 79 | 80 | let mut received = Vec::with_capacity(LEN); 81 | iotry!(server.read_to_end(&mut received)); 82 | assert!(!received.is_empty()); 83 | assert_eq!(received.len(), data.len()); 84 | assert_eq!(received, data); 85 | assert!(child.join().is_ok()); 86 | } 87 | 88 | #[test] 89 | fn test_stream_large_data() { 90 | // Has to be sent over several packets 91 | const LEN: usize = 1024 * 1024; 92 | let data: Vec = (0..LEN).map(|idx| idx as u8).collect(); 93 | assert_eq!(LEN, data.len()); 94 | 95 | let d = data.clone(); 96 | let server_addr = next_test_ip4(); 97 | let mut server = iotry!(UtpStream::bind(server_addr)); 98 | 99 | let child = thread::spawn(move || { 100 | let mut client = iotry!(UtpStream::connect(server_addr)); 101 | iotry!(client.write(&d[..])); 102 | iotry!(client.close()); 103 | }); 104 | 105 | let mut received = Vec::with_capacity(LEN); 106 | iotry!(server.read_to_end(&mut received)); 107 | assert!(!received.is_empty()); 108 | assert_eq!(received.len(), data.len()); 109 | assert_eq!(received, data); 110 | assert!(child.join().is_ok()); 111 | } 112 | 113 | #[test] 114 | fn test_stream_successive_reads() { 115 | const LEN: usize = 1024; 116 | let data: Vec = (0..LEN).map(|idx| idx as u8).collect(); 117 | assert_eq!(LEN, data.len()); 118 | 119 | let d = data.clone(); 120 | let server_addr = next_test_ip4(); 121 | let mut server = iotry!(UtpStream::bind(server_addr)); 122 | 123 | let child = thread::spawn(move || { 124 | let mut client = iotry!(UtpStream::connect(server_addr)); 125 | iotry!(client.write(&d[..])); 126 | iotry!(client.close()); 127 | }); 128 | 129 | let mut received = Vec::with_capacity(LEN); 130 | iotry!(server.read_to_end(&mut received)); 131 | assert!(!received.is_empty()); 132 | assert_eq!(received.len(), data.len()); 133 | assert_eq!(received, data); 134 | 135 | assert_eq!(server.read(&mut received).unwrap(), 0); 136 | assert!(child.join().is_ok()); 137 | } 138 | 139 | #[test] 140 | fn test_local_addr() { 141 | use std::net::ToSocketAddrs; 142 | 143 | let addr = next_test_ip4(); 144 | let addr = addr.to_socket_addrs().unwrap().next().unwrap(); 145 | let stream = UtpStream::bind(addr).unwrap(); 146 | 147 | assert!(stream.local_addr().is_ok()); 148 | assert_eq!(stream.local_addr().unwrap(), addr); 149 | } 150 | --------------------------------------------------------------------------------