summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchenzizhan <[email protected]>2023-09-01 13:49:31 +0800
committerchenzizhan <[email protected]>2023-09-01 13:49:31 +0800
commit43d05c31672ed47ee393df63a34db9ecfdea2960 (patch)
tree26cbba3777317ffce46d1a360ff292cea3ca068b
parent5771af7a4777df971ff3794742f6263e6b014b18 (diff)
TransferringStateWrapper
-rw-r--r--src/lib.rs2
-rw-r--r--src/session/callbacks.rs89
-rw-r--r--src/session/tcp_session.rs400
3 files changed, 391 insertions, 100 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 0ed362f..4321c02 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,3 +1,5 @@
+#![allow(dead_code)]
+
pub mod packet;
pub mod protocol;
pub mod session; \ No newline at end of file
diff --git a/src/session/callbacks.rs b/src/session/callbacks.rs
index 6a31d18..2be75b4 100644
--- a/src/session/callbacks.rs
+++ b/src/session/callbacks.rs
@@ -1,53 +1,90 @@
-use std::net::{TcpListener, TcpStream};
+// use std::net::{TcpListener, TcpStream};
use super::tcp_session;
-pub(super) enum SendTo {
- send_console,
- // send_file(String),
- // send_tcp(TcpStream),
+
+pub(super) enum Policy {
+ TcpSendConsole,
+}
+
+pub(super) struct ActionManager {
+ // todo: read toml and config.
}
-pub(super) trait TcpCB{
- fn run(&self, sender:SendTo);
+impl ActionManager {
+ pub fn gen_action(&self, policy: Policy) -> Box<dyn TcpCallBackAction> {
+ match policy {
+ Policy::TcpSendConsole => {
+ Box::new(SendCB {
+ buf: Vec::new(),
+ send_to: SendTo::SendConsole,
+ })
+ },
+ }
+ }
}
-trait ReadPeer: TcpCB {
+
+pub(super) trait TcpCallBackAction{
+ fn run(&self);
fn read_peer(&mut self, peer: &tcp_session::Peer);
}
+
+/* --------------------------------- SendCB --------------------------------- */
+enum SendTo {
+ SendConsole,
+}
+
pub(super) struct SendCB
{
buf: Vec<u8>,
+ send_to: SendTo,
}
-impl TcpCB for SendCB {
- fn run(&self, sender:SendTo) {
- match sender {
- SendTo::send_console => {
+
+impl TcpCallBackAction for SendCB {
+ fn run(&self) {
+ match self.send_to {
+ SendTo::SendConsole => {
println!("SendCB::run");
println!("{:?}", self.buf);
},
}
}
-}
-impl ReadPeer for SendCB {
fn read_peer(&mut self, peer: &tcp_session::Peer) {
-
println!("SendCB::read_peer");
- println!("{:?}", peer.map);
+ println!("{:?}", peer);
+ // todo: insert segment
}
}
-/* ------------------------------------------------------------------------ */
-pub(super) struct DebugCB {
+/* ----------------------------ModuleCb------------------------------------- */
+pub(super) struct ModuleCb {
+
}
-impl TcpCB for DebugCB {
- fn run(&self, sender:SendTo) {
- match sender {
- SendTo::send_console => {
- println!("DebugCB::run");
- },
- }
+impl TcpCallBackAction for ModuleCb {
+ fn run(&self) {
+ println!("ModuleCb::run");
+ }
+ fn read_peer(&mut self, peer: &tcp_session::Peer) {
+ println!("ModuleCb::read_peer");
}
}
-// more call backs here \ No newline at end of file
+// more call backs here
+
+
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_callbacks() {
+ let action_manager = ActionManager{};
+ let action = action_manager.gen_action(Policy::TcpSendConsole);
+ action.run();
+
+
+ println!("hahahahaczzzzzzx");
+ }
+} \ No newline at end of file
diff --git a/src/session/tcp_session.rs b/src/session/tcp_session.rs
index 460c0c8..238db38 100644
--- a/src/session/tcp_session.rs
+++ b/src/session/tcp_session.rs
@@ -3,10 +3,10 @@ use std::net::Ipv4Addr;
use std::marker::PhantomData;
use std::fmt::{self, Debug, Formatter};
use std::collections::BTreeMap;
-use std::vec;
-use crate::protocol::tcp::TcpHeader;
-use super::callbacks::{self, SendTo, SendCB};
+use crate::packet;
+use crate::protocol::tcp::{TcpHeader, TcpOption};
+use super::callbacks::{self, Policy};
#[derive(Debug)]
@@ -18,10 +18,7 @@ struct SynReceived;
#[derive(Debug)]
struct Established;
#[derive(Debug)]
-struct FinWait1
-{
-
-}
+struct FinWait1;
#[derive(Debug)]
struct FinWait2;
#[derive(Debug)]
@@ -48,21 +45,13 @@ impl SessionState for LastAck{}
impl SessionState for TimeWait{}
impl SessionState for Closed{}
-
-// todo: 其实应该是分成:状态检查的部分、回调部分和处理包的部分
-// 状态检查主要是状态和syn 码
-// 回调是用户提供的+自己的,需要有一套”什么时候触发“的描述。自己的回调是删包。以及各种情况下的发包,发包里面还有回调。。
-// 这个回调是要改变client 状态的。具体做啥?
-// 处理包:主要是一个tree map,
-// 具体是三个函数 handle_established_connection start 和end,它们有独立的处理逻辑。
-
enum TcpSessionErr {
WrongPacket(String),
- NoWindowScale,
+ NoWindowSpace,
}
#[derive(Debug)]
-struct TcpSegment {
+pub struct TcpSegment {
seq: u32,
payload: Vec<u8>,
}
@@ -90,7 +79,8 @@ pub(super) struct Peer {
isn: u32, // initial sequence number
next_seq: u32, // next sequence number
- wscale: u16, // window scale in tcp options
+ total_win: u16, // window scale in tcp options
+ used_win: u16, // used window size
ip: Ipv4Addr,
port: u16,
pub map: BTreeMap<u32, TcpSegment>
@@ -114,14 +104,24 @@ impl Peer {
ian: 0,
isn: 0,
next_seq: 0,
- wscale: 0,
+ total_win: 0,
+ used_win: 0,
ip: Ipv4Addr::new(0, 0, 0, 0),
port: 0,
map: BTreeMap::new(),
}
}
fn as_sender(&mut self, packet: &Packet) {
- self.wscale = packet.tcp_header.window;
+ let mut scale = 0;
+ if let Some(options) = &packet.tcp_header.options {
+ for option in options {
+ if let TcpOption::WSCALE{length, shift_count} = option {
+ scale = *shift_count;
+ }
+ }
+ }
+
+ self.total_win = packet.tcp_header.window << scale;
self.ip = packet.ip_src.clone();
self.port = packet.tcp_header.source_port;
self.isn = packet.tcp_header.seq_num;
@@ -130,24 +130,16 @@ impl Peer {
fn as_receiver(&mut self, packet: &Packet) {
self.ian = packet.tcp_header.seq_num;
}
- fn insert_segment(&mut self, packet: &Packet) {
+ fn add_segment(&mut self, packet: &Packet) {
self.map.insert(packet.tcp_header.seq_num,
TcpSegment::new(packet.tcp_header.seq_num, packet.segment.payload.clone())
);
- // update next_seq
- let mut next_seq = self.next_seq;
- for (seq, segment) in self.map.iter() {
- if *seq == next_seq {
- next_seq += segment.payload.len() as u32;
- } else {
- break;
- }
- }
+ self.used_win += packet.segment.payload.len() as u16;
}
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
enum ClosingBy {
Nil,
Client,
@@ -155,8 +147,6 @@ enum ClosingBy {
Closed,
}
-
-
#[derive(Debug)]
struct TransferringState<'a, SSender: SessionState, SReceiver: SessionState>{
client: &'a mut Peer,
@@ -166,6 +156,180 @@ struct TransferringState<'a, SSender: SessionState, SReceiver: SessionState>{
q: PhantomData<SReceiver>,
}
+impl<'a, SSender: SessionState, SReceiver: SessionState> Default for TransferringState<'a, SSender, SReceiver> {
+ fn default() -> Self {
+ TransferringState {
+ client: panic!("Default not implemented for client"), // You can't provide a default for a reference
+ server: panic!("Default not implemented for server"), // You can't provide a default for a reference
+ closing_by: ClosingBy::Nil,
+ p: PhantomData,
+ q: PhantomData,
+ }
+ }
+}
+
+// wave hand:
+// Peer side
+// Established send fin -> FinWait1* Established receive fin -> CloseWait
+// finwait1 receive ack -> FinWait2 CloseWait send ack -> CloseWait*
+// finwait2 receive fin -> TimeWait CloseWait send fin ->LastAck*
+// timewait send ack -> timewait LastAck receive ack -> Closed
+
+// closing temporary state:
+// finwait1 receive fin -> Closing Established send syn -> FinWait1
+// (just wait) FinWait1 receive fin -> Closing
+// Closing send ack -> Closing Closing send ack -> closing
+// Closing receive ack -> timewait Closing receive ack -> timewait
+enum TransferringStateWrapper<'a> {
+ Closed(TransferringState<'a, Closed, Closed>), // initial and end
+ SynSent(TransferringState<'a, SynSent, Listen>), // the client start a connection
+ SynReceived(TransferringState<'a, SynReceived, SynSent>), // server ack the syn packet
+ Established(TransferringState<'a, Established, Established>), // 3 way handshake done
+ FinWait1(TransferringState<'a, FinWait1, CloseWait>), // one of(either client or server) peer sends fin|rst and turn to FinWait1
+ FinWait2(TransferringState<'a, FinWait2, CloseWait>), // receive ack
+ LastAck(TransferringState<'a, LastAck, TimeWait>), // the side peer send fin on receiving fin that initiated by the other peer
+ TimeWait(TransferringState<'a, TimeWait, Closed>), // 4-way handshake done
+ Closing1(TransferringState<'a, FinWait1, Closing>), // one of Established state send syn and turn to FinWait1, while its peer, which has already sent syn and were being in FinWait1 state, receive syn and turn to Closing state
+ Closing2(TransferringState<'a, Closing, Closing>), // both peers enter the temporary Closing state
+ BothTimeWait1(TransferringState<'a, Closing, TimeWait>), // closing receive ack and turn to timewait
+ BothTimeWait2(TransferringState<'a, TimeWait, TimeWait>), // closing receive ack and turn to timewait
+}
+
+impl<'a> TransferringStateWrapper<'a> {
+ fn step(&mut self, packet: Packet) -> Result<(), TcpSessionErr> {
+ match *self {
+ /* --------------------------- 3 way handshake --------------------------- */
+ TransferringStateWrapper::Closed(state) => {
+ if !packet.tcp_header.flag_syn {
+ return Err(TcpSessionErr::WrongPacket("Closed server expect syn packet".to_string()));
+ }
+ *self = TransferringStateWrapper::SynSent(TransferringState{
+ client: state.client,
+ server: state.server,
+ ..Default::default()
+ });
+ },
+ TransferringStateWrapper::SynSent(state) => {
+ if !packet.tcp_header.flag_syn || !packet.tcp_header.flag_ack {
+ return Err(TcpSessionErr::WrongPacket("Client expects syn + ack packet to establish connection".to_string()));
+ }
+ *self = TransferringStateWrapper::SynReceived(TransferringState{
+ client: state.client,
+ server: state.server,
+ ..Default::default()
+ });
+ },
+ TransferringStateWrapper::SynReceived(state) => {
+ if !packet.tcp_header.flag_ack {
+ return Err(TcpSessionErr::WrongPacket("Server expects ack packet to establish connection".to_string()));
+ }
+ *self = TransferringStateWrapper::Established(TransferringState{
+ client: state.client,
+ server: state.server,
+ ..Default::default()
+ });
+ },
+
+ /* --------------------------- established & 4 way handshake --------------------------- */
+ TransferringStateWrapper::Established(state) => {
+ if !packet.tcp_header.flag_ack && !packet.tcp_header.flag_fin && !packet.tcp_header.flag_rst {
+ return Err(TcpSessionErr::WrongPacket("During transferring, every packet must carry ack, fin or rst flag.".to_string()));
+ }
+
+ if packet.tcp_header.flag_fin || packet.tcp_header.flag_rst {
+ *self = TransferringStateWrapper::FinWait1(TransferringState{
+ client: state.client,
+ server: state.server,
+ ..Default::default()
+ });
+ }
+ },
+ TransferringStateWrapper::FinWait1(state) => {
+ if !packet.tcp_header.flag_ack || !packet.tcp_header.flag_fin {
+ return Err(TcpSessionErr::WrongPacket("During FinWait1, wrong packet flag.".to_string()));
+ }
+ if packet.tcp_header.flag_ack {
+ *self = TransferringStateWrapper::FinWait2(TransferringState{
+ client: state.client,
+ server: state.server,
+ ..Default::default()
+ });
+ } else {
+ *self = TransferringStateWrapper::Closing1(TransferringState{
+ client: state.client,
+ server: state.server,
+ ..Default::default()
+ });
+ }
+ }
+ TransferringStateWrapper::FinWait2(state) => {
+ if !packet.tcp_header.flag_fin {
+ return Err(TcpSessionErr::WrongPacket("During FinWait2, wrong packet flag, expecting fin".to_string()));
+ }
+ *self = TransferringStateWrapper::LastAck(TransferringState{
+ client: state.client,
+ server: state.server,
+ ..Default::default()
+ });
+ }
+ TransferringStateWrapper::LastAck(state) => {
+ if !packet.tcp_header.flag_ack {
+ return Err(TcpSessionErr::WrongPacket("During LastAck, wrong packet flag, expecting ack".to_string()));
+ }
+
+ *self = TransferringStateWrapper::TimeWait(TransferringState{
+ client: state.client,
+ server: state.server,
+ ..Default::default()
+ });
+ }
+ TransferringStateWrapper::TimeWait(state) => {
+ // do nothing. Just throw away the redundant packets when in TimeWait state
+ }
+
+ /* --------------------------------- closing -------------------------------- */
+ TransferringStateWrapper::Closing1(state) => {
+ if !packet.tcp_header.flag_syn {
+ return Err(TcpSessionErr::WrongPacket("During Closing1, wrong packet flag, expecting syn".to_string()));
+ }
+
+ *self = TransferringStateWrapper::Closing2(TransferringState{
+ client: state.client,
+ server: state.server,
+ ..Default::default()
+ });
+ }
+ TransferringStateWrapper::Closing2(state) => {
+ if !packet.tcp_header.flag_ack {
+ return Err(TcpSessionErr::WrongPacket("A peer in closing state expects ack".to_string()));
+ }
+
+ *self = TransferringStateWrapper::BothTimeWait1(TransferringState{
+ client: state.client,
+ server: state.server,
+ ..Default::default()
+ });
+ }
+ TransferringStateWrapper::BothTimeWait1(state) => {
+ // todo: 如果是重复发包,也就是主动关闭的那方收到的ack,就直接return, 这个检查放到状态机外面的前面
+ if !packet.tcp_header.flag_ack {
+ return Err(TcpSessionErr::WrongPacket("A peer in closing state expects ack".to_string()));
+ }
+
+ *self = TransferringStateWrapper::BothTimeWait2(TransferringState{
+ client: state.client,
+ server: state.server,
+ ..Default::default()
+ });
+ }
+ TransferringStateWrapper::BothTimeWait2(_) => {
+ // do nothing.Just throw away the redundant packets when in TimeWait state
+ }
+ }
+ Ok(())
+ }
+}
+
impl<'a, T1:SessionState, T2:SessionState> From<(&'a mut Peer, &'a mut Peer)> for TransferringState<'a, T1, T2> {
fn from((client,server): (&'a mut Peer, &'a mut Peer)) -> Self {
TransferringState {
@@ -178,8 +342,8 @@ impl<'a, T1:SessionState, T2:SessionState> From<(&'a mut Peer, &'a mut Peer)> fo
}
}
-trait SessionStateMachine<'a, SSender: SessionState, SReceiver: SessionState, T: callbacks::TcpCB> {
- fn next_state(&'a mut self, packet: & Packet) -> Result<(TransferringState<'a, SSender, SReceiver>, Vec<T>), TcpSessionErr>;
+trait SessionStateMachine<'a, SSender: SessionState, SReceiver: SessionState> {
+ fn next_state(&'a mut self, packet: & Packet) -> Result<(TransferringState<'a, SSender, SReceiver>, Option<Policy>), TcpSessionErr>;
}
pub struct Session {
@@ -187,8 +351,8 @@ pub struct Session {
server: Peer,
}
-impl<'a> SessionStateMachine<'a, SynSent, Listen, callbacks::DebugCB> for TransferringState<'a, Closed, Closed> {
- fn next_state(&'a mut self, packet: &Packet) -> Result<(TransferringState<'a, SynSent, Listen>, Vec<callbacks::DebugCB>), TcpSessionErr> {
+impl<'a> SessionStateMachine<'a, SynSent, Listen> for TransferringState<'a, Closed, Closed> {
+ fn next_state(&'a mut self, packet: &Packet) -> Result<(TransferringState<'a, SynSent, Listen>, Option<Policy>), TcpSessionErr> {
if !packet.tcp_header.flag_syn {
return Err(TcpSessionErr::WrongPacket("Closed server expect syn packet".to_string()));
}
@@ -202,18 +366,17 @@ impl<'a> SessionStateMachine<'a, SynSent, Listen, callbacks::DebugCB> for Transf
closing_by: ClosingBy::Nil,
p: PhantomData,
q: PhantomData,
- }, vec![callbacks::DebugCB{}]
- ))
+ }, None))
}
}
-impl<'a> SessionStateMachine<'a, SynReceived, Listen, callbacks::SendCB> for TransferringState<'a, Closed, Closed> {
- fn next_state(&'a mut self, packet: &Packet) -> Result<(TransferringState<'a, SynReceived, Listen>, Vec<callbacks::SendCB>), TcpSessionErr> {
+impl<'a> SessionStateMachine<'a, SynReceived, SynSent> for TransferringState<'a, SynSent, Listen> {
+ fn next_state(&'a mut self, packet: &Packet) -> Result<(TransferringState<'a, SynReceived, SynSent>, Option<Policy>), TcpSessionErr> {
if !packet.tcp_header.flag_syn || !packet.tcp_header.flag_ack {
return Err(TcpSessionErr::WrongPacket("Client expects syn + ack packet to establish connection".to_string()));
}
- self.client.state = Box::new(SynReceived);
- self.server.state = Box::new(Listen);
+ self.client.state = Box::new(SynSent);
+ self.server.state = Box::new(SynReceived);
self.client.as_receiver(packet);
self.server.as_sender(packet);
Ok(
@@ -223,15 +386,13 @@ impl<'a> SessionStateMachine<'a, SynReceived, Listen, callbacks::SendCB> for Tra
closing_by: ClosingBy::Nil,
p: PhantomData,
q: PhantomData,
- },
- Vec::new()
- )
+ }, None)
)
}
}
-impl<'a> SessionStateMachine<'a, Established, Established, callbacks::SendCB> for TransferringState<'a, SynReceived, Listen> {
- fn next_state(&'a mut self, packet: & Packet) -> Result<(TransferringState<'a, Established, Established>, Vec<callbacks::SendCB>), TcpSessionErr> {
+impl<'a> SessionStateMachine<'a, Established, Established> for TransferringState<'a, SynReceived, SynSent> {
+ fn next_state(&'a mut self, packet: & Packet) -> Result<(TransferringState<'a, Established, Established>, Option<Policy>), TcpSessionErr> {
if !packet.tcp_header.flag_ack {
return Err(TcpSessionErr::WrongPacket("Server expects ack packet to establish connection".to_string()));
}
@@ -243,25 +404,51 @@ impl<'a> SessionStateMachine<'a, Established, Established, callbacks::SendCB> fo
closing_by: ClosingBy::Nil,
p: PhantomData,
q: PhantomData,
- }, Vec::new()
- ))
+ }, None))
}
}
-impl<'a> SessionStateMachine<'a, FinWait1, CloseWait, callbacks::SendCB> for TransferringState<'a, Established, Established> {
- fn next_state(&'a mut self, packet: & Packet) -> Result<(TransferringState<'a, FinWait1, CloseWait>, Vec<callbacks::SendCB>), TcpSessionErr> {
- // determine the sender
- let (sender, receiver) = {
- if packet.tcp_header.source_port == self.client.port && packet.ip_src == self.client.ip {
- (self.client, self.server)
+fn sender_operation_for_establised(sender: &mut Peer, packet: &Packet) -> Result<(), TcpSessionErr> {
+ let payload_len = packet.segment.payload.len() as u16;
+ if sender.used_win + payload_len >= sender.total_win {
+ return Err(TcpSessionErr::NoWindowSpace);
+ }
+ if payload_len > 0 {
+ sender.add_segment(packet);
+ }
+ sender.next_seq += {
+ if packet.tcp_header.flag_fin || packet.tcp_header.flag_rst {
+ 1
+ } else {
+ if packet.tcp_header.seq_num < sender.next_seq { // segments out of order
+ 0
} else {
- (self.server, self.client)
+ packet.segment.payload.len() as u32
}
- };
- // todo: window and payload check
- if packet.tcp_header.flag_fin { // todo: reset?
- sender.state = Box::new(FinWait1);
- receiver.state = Box::new(CloseWait);
+ }
+ };
+ if (packet.tcp_header.flag_fin || packet.tcp_header.flag_rst) && sender.next_seq == sender.ian {
+ sender.state = Box::new(FinWait1);
+ }
+ Ok(())
+}
+
+impl<'a> SessionStateMachine<'a, FinWait1, CloseWait> for TransferringState<'a, Established, Established> {
+ fn next_state(&'a mut self, packet: & Packet) -> Result<(TransferringState<'a, FinWait1, CloseWait>, Option<Policy>), TcpSessionErr> {
+ // determine the sender
+ if !packet.tcp_header.flag_ack && !packet.tcp_header.flag_fin && !packet.tcp_header.flag_rst {
+ return Err(TcpSessionErr::WrongPacket("During transferring, every packet must carry ack, fin or rst flag.".to_string()));
+ }
+
+ if packet.tcp_header.source_port == self.client.port && packet.ip_src == self.client.ip {
+ sender_operation_for_establised(&mut self.client, packet)?;
+ self.server.state = Box::new(CloseWait);
+ } else {
+ sender_operation_for_establised(&mut self.server, packet)?;
+ self.client.state = Box::new(CloseWait);
+ }
+
+ if packet.tcp_header.flag_fin || packet.tcp_header.flag_rst {
self.closing_by = {
if packet.tcp_header.source_port == self.client.port && packet.ip_src == self.client.ip {
ClosingBy::Client
@@ -269,17 +456,76 @@ impl<'a> SessionStateMachine<'a, FinWait1, CloseWait, callbacks::SendCB> for Tra
ClosingBy::Server
}
};
- // todo: close connection callbacks
- } else if packet.tcp_header.flag_ack {
- // state remain the same
- // packet proc
- } else {
- return Err(TcpSessionErr::WrongPacket("During transferring, every packet must carry ack flag.".to_string()));
}
-
+ Ok((TransferringState{
+ client: self.client,
+ server: self.server,
+ closing_by: self.closing_by.clone(),
+ p: PhantomData,
+ q: PhantomData,
+ }, None))
}
}
+impl<'a> SessionStateMachine<'a, CloseWait, FinWait2> for TransferringState<'a, FinWait1, CloseWait> {
+ fn next_state(&'a mut self, packet: & Packet) -> Result<(TransferringState<'a, CloseWait, FinWait2>, Option<Policy>), TcpSessionErr> {
+ // if !packet.tcp_header.flag_ack {
+ // return Err(TcpSessionErr::WrongPacket("During closing, wrong packet flag.".to_string()));
+ // }
+
+ // (sender, receiver) = match self.closing_by {
+ // ClosingBy::Client: {
+ // (self.server, self.client)
+ // },
+ // ClosingBy::Server: {
+ // (self.client, self.server)
+ // },
+ // _: {
+ // return Err(TcpSessionErr::WrongPacket("During closing, wrong packet.".to_string()));
+ // }
+ // }
+ return Err(TcpSessionErr::WrongPacket("try1.".to_string()));
+ }
+}
+
+impl<'a> SessionStateMachine<'a, LastAck, TimeWait> for TransferringState<'a, FinWait1, CloseWait> {
+ fn next_state(&'a mut self, packet: & Packet) -> Result<(TransferringState<'a, LastAck, TimeWait>, Option<Policy>), TcpSessionErr> {
+ return Err(TcpSessionErr::WrongPacket("try2.".to_string()));
+ }
+}
+
+// impl<'a> SessionStateMachine<'a, FinWait1, CloseWait, callbacks::SendCB> for TransferringState<'a, Established, Established> {
+// fn next_state(&'a mut self, packet: & Packet) -> Result<(TransferringState<'a, FinWait1, CloseWait>, Vec<callbacks::SendCB>), TcpSessionErr> {
+// // determine the sender
+// let (sender, receiver) = {
+// if packet.tcp_header.source_port == self.client.port && packet.ip_src == self.client.ip {
+// (self.client, self.server)
+// } else {
+// (self.server, self.client)
+// }
+// };
+// // todo: window and payload check
+// if packet.tcp_header.flag_fin { // todo: reset?
+// sender.state = Box::new(FinWait1);
+// receiver.state = Box::new(CloseWait);
+// self.closing_by = {
+// if packet.tcp_header.source_port == self.client.port && packet.ip_src == self.client.ip {
+// ClosingBy::Client
+// } else {
+// ClosingBy::Server
+// }
+// };
+// // todo: close connection callbacks
+// } else if packet.tcp_header.flag_ack {
+// // state remain the same
+// // packet proc
+// } else {
+// return Err(TcpSessionErr::WrongPacket("During transferring, every packet must carry ack flag.".to_string()));
+// }
+
+// }
+// }
+
// // fn next_peers<'a>(client: &'a mut Peer, server: &'a mut Peer, packet: &'a TcpHeader) -> (&'a Peer, &'a Peer) {
// // match (client.state, server.state) {
// // (SessionState::Closed, SessionState::Closed) => {
@@ -337,7 +583,7 @@ mod tests {
client: Peer::new(),
server: Peer::new(),
};
- let packet = TcpHeader {
+ let tcp = TcpHeader {
source_port: 50081,
dest_port: 443,
seq_num: 1522577104,
@@ -355,12 +601,18 @@ mod tests {
urgent_ptr: 0,
options: None,
};
+ let packet = Packet {
+ ip_dst: Ipv4Addr::new(192, 168, 1, 1),
+ ip_src: Ipv4Addr::new(192, 168, 1, 2),
+ tcp_header: tcp,
+ segment: TcpSegment::new(0, vec![]),
+ };
- let mut state:TransferringState<Closed, Closed> = (&mut session.client, &mut session.server).into();
- let state: TransferringState<'_, SynSent, Listen> = state.next_state(&packet);
+ let mut state:TransferringState<FinWait1, CloseWait> = TransferringState::from((&mut session.client, &mut session.server));
+ let state = state.next_state(&packet);
- println!("hahahahahahaahhaha");
- println!("{:?}", state);
+ // println!("hahahahahahaahhaha");
+ // println!("{:?}", state);
}
}