mirror of
https://github.com/YGGverse/aquatic.git
synced 2026-03-31 17:55:36 +00:00
aquatic_ws: convert ipv4-mapped ipv6 addresses to ipv4 (for state split)
This commit is contained in:
parent
4067e420c3
commit
809d16919d
4 changed files with 25 additions and 14 deletions
8
TODO.md
8
TODO.md
|
|
@ -2,9 +2,6 @@
|
|||
|
||||
## General
|
||||
|
||||
* use ipv4-mapped address functions, but I should check that they really
|
||||
work as they really work as they should. All announces over ipv4 should
|
||||
go to ipv4 map, all over ipv6 to ipv6 map
|
||||
* init logging in cli helper crate?
|
||||
|
||||
## aquatic_http_load_test
|
||||
|
|
@ -30,13 +27,14 @@
|
|||
write actually block here? And what action should be taken then?
|
||||
|
||||
## aquatic_ws
|
||||
* test transfer again with crossbeam-channel
|
||||
* test transfer again with changes made:
|
||||
* crossbeam-channel
|
||||
* ipv6/ipv4 mapping
|
||||
* is 'key' sent in announce request? if so, maybe handle it like in
|
||||
aquatic_http (including ip uniqueness part of peer map key)
|
||||
* established connections do not get valid_until updated, I think?
|
||||
* tests
|
||||
* use enum as return type for handshake machine
|
||||
* ipv4 and ipv6 state split: think about this more..
|
||||
|
||||
## aquatic_udp
|
||||
* mio: set oneshot for epoll and kqueue? otherwise, stop reregistering?
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::net::SocketAddr;
|
||||
use std::net::{SocketAddr, IpAddr};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crossbeam_channel::{Sender, Receiver};
|
||||
|
|
@ -18,7 +18,10 @@ pub struct ConnectionMeta {
|
|||
/// Index of socket worker responsible for this connection. Required for
|
||||
/// sending back response through correct channel to correct worker.
|
||||
pub worker_index: usize,
|
||||
pub peer_addr: SocketAddr,
|
||||
/// Peer address as received from socket, meaning it wasn't converted to
|
||||
/// an IPv4 address if it was a IPv4-mapped IPv6 address
|
||||
pub naive_peer_addr: SocketAddr,
|
||||
pub converted_peer_ip: IpAddr,
|
||||
pub poll_token: Token,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ pub fn handle_announce_requests(
|
|||
let valid_until = ValidUntil::new(config.cleaning.max_peer_age);
|
||||
|
||||
for (request_sender_meta, request) in requests {
|
||||
let torrent_data: &mut TorrentData = if request_sender_meta.peer_addr.is_ipv4(){
|
||||
let torrent_data: &mut TorrentData = if request_sender_meta.converted_peer_ip.is_ipv4(){
|
||||
torrent_maps.ipv4.entry(request.info_hash).or_default()
|
||||
} else {
|
||||
torrent_maps.ipv6.entry(request.info_hash).or_default()
|
||||
|
|
@ -102,9 +102,11 @@ pub fn handle_announce_requests(
|
|||
// If there is already a peer with this peer_id, check that socket
|
||||
// addr is same as that of request sender. Otherwise, ignore request.
|
||||
// Since peers have access to each others peer_id's, they could send
|
||||
// requests using them, causing all sorts of issues.
|
||||
// requests using them, causing all sorts of issues. Checking naive
|
||||
// (non-converted) socket addresses is enough, since state is split
|
||||
// on converted peer ip.
|
||||
if let Some(previous_peer) = torrent_data.peers.get(&request.peer_id){
|
||||
if request_sender_meta.peer_addr != previous_peer.connection_meta.peer_addr {
|
||||
if request_sender_meta.naive_peer_addr != previous_peer.connection_meta.naive_peer_addr {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -177,7 +179,7 @@ pub fn handle_announce_requests(
|
|||
// possible to write a new version of that function which isn't
|
||||
// shared with aquatic_udp and goes about it differently
|
||||
// though.
|
||||
if request_sender_meta.peer_addr == offer_receiver.connection_meta.peer_addr {
|
||||
if request_sender_meta.naive_peer_addr == offer_receiver.connection_meta.naive_peer_addr {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -244,7 +246,7 @@ pub fn handle_scrape_requests(
|
|||
files: HashMap::with_capacity(num_to_take),
|
||||
};
|
||||
|
||||
let torrent_map: &mut TorrentMap = if meta.peer_addr.is_ipv4(){
|
||||
let torrent_map: &mut TorrentMap = if meta.converted_peer_ip.is_ipv4(){
|
||||
&mut torrent_maps.ipv4
|
||||
} else {
|
||||
&mut torrent_maps.ipv6
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ use mio::{Events, Poll, Interest, Token};
|
|||
use mio::net::TcpListener;
|
||||
use tungstenite::protocol::WebSocketConfig;
|
||||
|
||||
use aquatic_common::convert_ipv4_mapped_ipv6;
|
||||
|
||||
use crate::common::*;
|
||||
use crate::config::Config;
|
||||
use crate::protocol::*;
|
||||
|
|
@ -187,10 +189,16 @@ pub fn run_handshakes_and_read_messages(
|
|||
match established_ws.ws.read_message(){
|
||||
Ok(ws_message) => {
|
||||
if let Some(in_message) = InMessage::from_ws_message(ws_message){
|
||||
let naive_peer_addr = established_ws.peer_addr;
|
||||
let converted_peer_ip = convert_ipv4_mapped_ipv6(
|
||||
naive_peer_addr.ip()
|
||||
);
|
||||
|
||||
let meta = ConnectionMeta {
|
||||
worker_index: socket_worker_index,
|
||||
poll_token,
|
||||
peer_addr: established_ws.peer_addr
|
||||
naive_peer_addr,
|
||||
converted_peer_ip,
|
||||
};
|
||||
|
||||
debug!("read message");
|
||||
|
|
@ -249,7 +257,7 @@ pub fn send_out_messages(
|
|||
.and_then(Connection::get_established_ws);
|
||||
|
||||
if let Some(established_ws) = opt_established_ws {
|
||||
if established_ws.peer_addr != meta.peer_addr {
|
||||
if established_ws.peer_addr != meta.naive_peer_addr {
|
||||
info!("socket worker error: peer socket addrs didn't match");
|
||||
|
||||
continue;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue