blob: 793e07a5e2444adcd75cd29b00ae588cc02fef19 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! The Transmission Control Protocol (TCP).
mod conn;
mod listen;
mod types;
pub use self::types::*;
use std::collections::HashMap;
use std::num::NonZeroU16;
use packet::BufferMut;
use crate::ip::{Ip, IpAddr, Ipv4, Ipv6};
use crate::wire::tcp::{TcpParseArgs, TcpSegment};
use crate::{Context, EventDispatcher};
use self::conn::Conn;
use self::listen::Listener;
/// The state associated with the TCP protocol.
#[derive(Default)]
pub struct TcpState {
v4: TcpStateInner<Ipv4>,
v6: TcpStateInner<Ipv6>,
}
#[derive(Default)]
struct TcpStateInner<I: Ip> {
conns: HashMap<FourTuple<I::Addr>, Conn>,
listeners: HashMap<TwoTuple<I::Addr>, Listener>,
}
/// The identifier for timer events in the TCP layer.
#[derive(Copy, Clone, PartialEq)]
pub struct TcpTimerId {
// TODO
}
#[derive(Eq, PartialEq, Hash)]
struct TwoTuple<A: IpAddr> {
local_ip: A,
local_port: NonZeroU16,
}
#[derive(Eq, PartialEq, Hash)]
struct FourTuple<A: IpAddr> {
local_ip: A,
local_port: NonZeroU16,
remote_ip: A,
remote_port: NonZeroU16,
}
/// Receive a TCP segment in an IP packet.
pub fn receive_ip_packet<D: EventDispatcher, A: IpAddr, B: BufferMut>(
ctx: &mut Context<D>, src_ip: A, dst_ip: A, mut buffer: B,
) {
println!("received tcp packet: {:x?}", buffer.as_mut());
let segment = if let Ok(segment) =
buffer.parse_with::<_, TcpSegment<_>>(TcpParseArgs::new(src_ip, dst_ip))
{
segment
} else {
// TODO(joshlf): Do something with ICMP here?
return;
};
if segment.syn() {
let _key = TwoTuple {
local_ip: dst_ip,
local_port: segment.dst_port(),
};
// TODO(joshlf): Lookup and handle
} else {
let _key = FourTuple {
local_ip: dst_ip,
local_port: segment.dst_port(),
remote_ip: src_ip,
remote_port: segment.src_port(),
};
// TODO(joshlf): Lookup and handle
}
}