Commit fbf4d695 authored by Nawasan Wisitsingkhon's avatar Nawasan Wisitsingkhon

refactor: move tcp connection in main to new function and use by Controller

parent b8ceac6f
pub mod openflow; pub mod openflow;
pub mod etherparser; pub mod etherparser;
\ No newline at end of file
mod tcp_listener;
\ No newline at end of file
use std::io::Read; use tenjin::openflow::messages::Openflow10;
use std::net::TcpListener; use tenjin::openflow::Controller;
use tenjin::openflow::events::packet_in::PacketInEvent;
use tenjin::openflow::messages::{OfpMsg, Openflow10};
use tenjin::openflow::traiter::OfpMsgEvent;
use tenjin::openflow::{Controller, OfpHeader};
extern crate byteorder; extern crate byteorder;
fn main() -> Result<(), std::io::Error> { fn main() -> Result<(), std::io::Error> {
let mut controller = Controller::new(Openflow10::new()); let mut controller = Controller::new(Openflow10::new());
controller.listener("127.0.0.1:6633");
let listener = TcpListener::bind(("127.0.0.1", 6633)).unwrap();
let mut buf = vec![0u8; 8];
for stream in listener.incoming() {
println!("{:?}", stream);
match stream {
Ok(mut stream) => {
// std::thread::spawn(move || {
println!("=================== connection =======================");
// after tcp is connected, it will send hello message
controller.hello(&mut stream);
// loop for receive data
loop {
// first receive with Openflow header 64 bit to buf
match stream.read(&mut buf) {
Ok(v) if v > 0 => {
let packet = OfpHeader::parse(&buf);
// length_payload is var to receive payload if the packet has
// and assign size by length
let length_payload = packet.size();
let mut payload = vec![0u8; length_payload];
stream.read(&mut payload)?;
let message = controller.ofp.msg_parse(packet.message as u16);
match message {
// 0 is Hello message
OfpMsg::Hello => {
// after get Hello, send fetureReq
controller.fetures_req(packet.xid, &mut stream);
println!("Hello event");
}
OfpMsg::PacketIn => {
controller.packet_in(
packet.xid,
PacketInEvent::parse(&payload),
&mut stream,
);
println!("PacketIn event");
}
_ => {
println!("others message");
}
}
}
Ok(_) | Err(_) => break,
}
}
println!("======================================================");
// });
}
Err(_) => {
// connection failed
panic!("Connection failed")
}
}
}
Ok(()) Ok(())
} }
use std::{collections::HashMap, io::Write, net::TcpStream}; use std::{
collections::HashMap,
io::{Read, Write},
net::TcpStream,
};
use crate::tcp_listener::tcp_listener_handler;
use super::{ use super::{
events::PacketInEvent, events::PacketInEvent,
messages::traiter::{MessageMarshal, OfpMsgEvent}, messages::{
traiter::{MessageMarshal, OfpMsgEvent},
OfpMsg,
},
OfpHeader,
}; };
pub struct Controller<OME: OfpMsgEvent> { pub struct Controller<OME: OfpMsgEvent> {
...@@ -23,6 +33,26 @@ impl<OME: OfpMsgEvent> Controller<OME> { ...@@ -23,6 +33,26 @@ impl<OME: OfpMsgEvent> Controller<OME> {
} }
} }
pub fn listener(&mut self, address: &str) {
tcp_listener_handler(self, address);
}
pub fn request_handler(&mut self, buf: &mut Vec<u8>, stream: &mut TcpStream) {
let ofp_header = OfpHeader::parse(&buf);
let mut payload = vec![0u8; ofp_header.pkt_size()];
let _ = stream.read(&mut payload);
let message = self.ofp.msg_parse(ofp_header.message as u16);
match message {
OfpMsg::Hello => self.send_msg(self.ofp.fetures_req(), ofp_header.xid, stream),
OfpMsg::FeaturesReq => todo!(),
OfpMsg::PacketIn => {
self.packet_in_handler(ofp_header.xid, PacketInEvent::parse(&payload), stream);
}
OfpMsg::FlowMod => todo!(),
OfpMsg::NotFound => todo!(),
}
}
pub fn send_msg<T: MessageMarshal>(&self, msg: T, xid: u32, stream: &mut TcpStream) { pub fn send_msg<T: MessageMarshal>(&self, msg: T, xid: u32, stream: &mut TcpStream) {
let mut header_bytes: Vec<u8> = Vec::new(); let mut header_bytes: Vec<u8> = Vec::new();
let mut body_bytes: Vec<u8> = Vec::new(); let mut body_bytes: Vec<u8> = Vec::new();
...@@ -49,7 +79,7 @@ impl<OME: OfpMsgEvent> Controller<OME> { ...@@ -49,7 +79,7 @@ impl<OME: OfpMsgEvent> Controller<OME> {
self.send_msg(fetreq_msg, xid, stream); self.send_msg(fetreq_msg, xid, stream);
} }
pub fn packet_in(&mut self, xid: u32, packetin: PacketInEvent, stream: &mut TcpStream) { pub fn packet_in_handler(&mut self, xid: u32, packetin: PacketInEvent, stream: &mut TcpStream) {
let ether = packetin.payload; let ether = packetin.payload;
self.mac_to_port.insert(ether.mac_src, packetin.port); self.mac_to_port.insert(ether.mac_src, packetin.port);
} }
......
...@@ -10,7 +10,10 @@ pub struct OfpHeader { ...@@ -10,7 +10,10 @@ pub struct OfpHeader {
} }
impl OfpHeader { impl OfpHeader {
pub fn size(&self) -> usize { pub fn header_size(&self) -> usize {
size_of::<OfpHeader>()
}
pub fn pkt_size(&self) -> usize {
return self.length as usize - size_of::<OfpHeader>(); return self.length as usize - size_of::<OfpHeader>();
} }
pub fn new(version: u8, message: u8, length: u16, xid: u32) -> Self { pub fn new(version: u8, message: u8, length: u16, xid: u32) -> Self {
......
use std::{io::Read, net::TcpListener};
use crate::openflow::{traiter::OfpMsgEvent, Controller};
pub fn tcp_listener_handler<OME: OfpMsgEvent>(controller: &mut Controller<OME>, address: &str) {
let listener = TcpListener::bind(address).unwrap();
/*
* buffer with 8 length that only support openflow 1.0
* I will make it support others version soon.
*/
let mut buffer = vec![0u8; 8];
for stream in listener.incoming() {
match stream {
Ok(mut stream) => {
controller.hello(&mut stream);
loop {
match stream.read(&mut buffer) {
Ok(v) if v > 0 => {
controller.request_handler(&mut buffer, &mut stream);
}
Ok(_) | Err(_) => panic!("Connection failed!"),
}
}
}
Err(_) => todo!(),
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment