diff options
author | sotech117 <michael_foiani@brown.edu> | 2023-11-08 18:02:03 -0500 |
---|---|---|
committer | sotech117 <michael_foiani@brown.edu> | 2023-11-08 18:02:03 -0500 |
commit | 921dd3c38a052861d0523e775efd2f1dac45ebcc (patch) | |
tree | c614bd2cb82418ff56fb76224757778d8088961f | |
parent | a571eee893bc308a75e66f37f908752bb1cbb321 (diff) |
get basic sending and reading to work
-rw-r--r-- | cmd/vhost/main.go | 16 | ||||
-rw-r--r-- | pkg/ipstack/ipstack.go | 272 | ||||
-rwxr-xr-x | vhost | bin | 3181890 -> 3191006 bytes | |||
-rwxr-xr-x | vrouter | bin | 3164418 -> 3182993 bytes |
4 files changed, 148 insertions, 140 deletions
diff --git a/cmd/vhost/main.go b/cmd/vhost/main.go index 7c32df8..6a78b97 100644 --- a/cmd/vhost/main.go +++ b/cmd/vhost/main.go @@ -7,8 +7,8 @@ import ( // "iptcp/pkg/tcpstack" "net/netip" "os" - "strings" "strconv" + "strings" ) func main() { @@ -85,7 +85,7 @@ func main() { } } } -// ********************************************TCP REPL*************************************************************** + // ********************************************TCP REPL*************************************************************** case "a": // accept a connection // get the port number @@ -102,14 +102,12 @@ func main() { continue } go func() { - for { - conn, err := listener.VAccept() - if err != nil { - fmt.Println(err) - } - sockets[conn.Socket] = conn + conn, err := listener.VAccept() + if err != nil { + fmt.Println(err) } - }() + sockets[conn.Socket] = conn + }() case "c": if len(tokens) != 3 { fmt.Println("Invalid command: ", line) diff --git a/pkg/ipstack/ipstack.go b/pkg/ipstack/ipstack.go index 0d317c2..9ffe34f 100644 --- a/pkg/ipstack/ipstack.go +++ b/pkg/ipstack/ipstack.go @@ -19,15 +19,15 @@ import ( ipv4header "github.com/brown-csci1680/iptcp-headers" "github.com/google/netstack/tcpip/header" "github.com/pkg/errors" - "iptcp/pkg/lnxconfig" "iptcp/pkg/iptcp_utils" + "iptcp/pkg/lnxconfig" "log" + "math/rand" "net" "net/netip" + "strings" "sync" "time" - "strings" - "math/rand" // "github.com/google/netstack/tcpip/header" ) @@ -896,17 +896,17 @@ func HandleTCP(src *Interface, message []byte, hdr *ipv4header.IPv4Header) error fmt.Println("no socket entry found") } else if socketEntry.State == Established { fmt.Println("socket entry found") - + // make ack header tcpHdr := &header.TCPFields{ - SrcPort: tcpHdr.DstPort, - DstPort: tcpHdr.SrcPort, - SeqNum: tcpHdr.SeqNum, - AckNum: tcpHdr.SeqNum + 1, - DataOffset: 20, - Flags: 0x10, - WindowSize: MAX_WINDOW_SIZE, - Checksum: 0, + SrcPort: tcpHdr.DstPort, + DstPort: tcpHdr.SrcPort, + SeqNum: tcpHdr.SeqNum, + AckNum: tcpHdr.SeqNum + 1, + DataOffset: 20, + Flags: 0x10, + WindowSize: MAX_WINDOW_SIZE, + Checksum: 0, UrgentPointer: 0, } // make the payload @@ -914,23 +914,27 @@ func HandleTCP(src *Interface, message []byte, hdr *ipv4header.IPv4Header) error if err != nil { fmt.Println(err) } - socketEntry.Conn.RecvBuffer.buffer = append(socketEntry.Conn.RecvBuffer.buffer, tcpPayload...) - socketEntry.Conn.RecvBuffer.recvNext += uint32(len(tcpPayload)) + ptr := socketEntry.Conn.RecvBuffer.recvNext + l := uint32(len(tcpPayload)) + copy(socketEntry.Conn.RecvBuffer.buffer[ptr:ptr+l], tcpPayload) + socketEntry.Conn.RecvBuffer.recvNext += l + fmt.Println("recvNext: ", socketEntry.Conn.RecvBuffer.recvNext) + fmt.Println("recvBuffer: ", socketEntry.Conn.RecvBuffer.buffer) break } // add to table if available mapMutex.Lock() for _, socketEntry := range VHostSocketMaps { // todo: check between all 4 field in tuple - if socketEntry.LocalPort == tcpHdr.DstPort && socketEntry.LocalIP == hdr.Dst.String() && socketEntry.State == Listening{ + if socketEntry.LocalPort == tcpHdr.DstPort && socketEntry.LocalIP == hdr.Dst.String() && socketEntry.State == Listening { // add a new socketEntry to the map newEntry := &SocketEntry{ - LocalPort: tcpHdr.DstPort, + LocalPort: tcpHdr.DstPort, RemotePort: tcpHdr.SrcPort, - LocalIP: hdr.Dst.String(), - RemoteIP: hdr.Src.String(), - State: SYNRECIEVED, - Socket: socketsMade, + LocalIP: hdr.Dst.String(), + RemoteIP: hdr.Src.String(), + State: SYNRECIEVED, + Socket: socketsMade, } // add the entry to the map key := SocketKey{hdr.Dst.String(), tcpHdr.DstPort, hdr.Src.String(), tcpHdr.SrcPort} @@ -950,14 +954,14 @@ func HandleTCP(src *Interface, message []byte, hdr *ipv4header.IPv4Header) error } // make the header tcpHdr := &header.TCPFields{ - SrcPort: tcpHdr.DstPort, - DstPort: tcpHdr.SrcPort, - SeqNum: tcpHdr.SeqNum, - AckNum: tcpHdr.SeqNum + 1, - DataOffset: 20, - Flags: 0x12, - WindowSize: MAX_WINDOW_SIZE, - Checksum: 0, + SrcPort: tcpHdr.DstPort, + DstPort: tcpHdr.SrcPort, + SeqNum: tcpHdr.SeqNum, + AckNum: tcpHdr.SeqNum + 1, + DataOffset: 20, + Flags: 0x12, + WindowSize: MAX_WINDOW_SIZE, + Checksum: 0, UrgentPointer: 0, } // make the payload @@ -982,14 +986,14 @@ func HandleTCP(src *Interface, message []byte, hdr *ipv4header.IPv4Header) error // send an ACK // make the header tcpHdr := &header.TCPFields{ - SrcPort: tcpHdr.DstPort, - DstPort: tcpHdr.SrcPort, - SeqNum: tcpHdr.SeqNum + 1, - AckNum: tcpHdr.SeqNum, - DataOffset: 20, - Flags: 0x10, - WindowSize: MAX_WINDOW_SIZE, - Checksum: 0, + SrcPort: tcpHdr.DstPort, + DstPort: tcpHdr.SrcPort, + SeqNum: tcpHdr.SeqNum + 1, + AckNum: tcpHdr.SeqNum, + DataOffset: 20, + Flags: 0x10, + WindowSize: MAX_WINDOW_SIZE, + Checksum: 0, UrgentPointer: 0, } // make the payload @@ -1007,13 +1011,13 @@ func HandleTCP(src *Interface, message []byte, hdr *ipv4header.IPv4Header) error socketEntry, in := VHostSocketMaps[key] if !in { fmt.Println("no socket entry found") - } else if (socketEntry.State == Established) { + } else if socketEntry.State == Established { fmt.Println("socket entry found") // socketEntry.Conn.RecvBuffer.buffer = append(socketEntry.Conn.RecvBuffer.buffer, tcpPayload...) socketEntry.Conn.SendBuffer.una += uint32(len(tcpPayload)) break } - + mapMutex.Lock() for _, socketEntry := range VHostSocketMaps { if socketEntry.LocalPort == tcpHdr.DstPort && socketEntry.LocalIP == hdr.Dst.String() && socketEntry.State == SYNRECIEVED { @@ -1025,9 +1029,8 @@ func HandleTCP(src *Interface, message []byte, hdr *ipv4header.IPv4Header) error break default: fmt.Println("I see a non TCP packet") - break + break } - return nil } @@ -1189,71 +1192,73 @@ func CleanUp() { // ************************************** TCP FUNCTIONS ********************************************************** type ConnectionState string + const ( - Established ConnectionState = "ESTABLISHED" - Listening ConnectionState = "LISTENING" - Closed ConnectionState = "CLOSED" - SYNSENT ConnectionState = "SYNSENT" - SYNRECIEVED ConnectionState = "SYNRECIEVED" - MAX_WINDOW_SIZE = 65535 + Established ConnectionState = "ESTABLISHED" + Listening ConnectionState = "LISTENING" + Closed ConnectionState = "CLOSED" + SYNSENT ConnectionState = "SYNSENT" + SYNRECIEVED ConnectionState = "SYNRECIEVED" + MAX_WINDOW_SIZE = 65535 ) -// VTCPListener represents a listener socket (similar to Go’s net.TCPListener) +// VTCPListener represents a listener socket (similar to Go’s net.TCPListener) type VTCPListener struct { - LocalAddr string - LocalPort uint16 + LocalAddr string + LocalPort uint16 RemoteAddr string RemotePort uint16 - Socket int - State ConnectionState + Socket int + State ConnectionState } // // VTCPConn represents a “normal” socket for a TCP connection between two endpoints (similar to Go’s net.TCPConn) type VTCPConn struct { LocalAddr string - LocalPort uint16 + LocalPort uint16 RemoteAddr string RemotePort uint16 - Socket int - State ConnectionState + Socket int + State ConnectionState SendBuffer *SendBuffer RecvBuffer *RecvBuffer } type SocketEntry struct { - Socket int - LocalIP string - LocalPort uint16 - RemoteIP string + Socket int + LocalIP string + LocalPort uint16 + RemoteIP string RemotePort uint16 - State ConnectionState - Conn *VTCPConn + State ConnectionState + Conn *VTCPConn } type SocketKey struct { - LocalIP string - LocalPort uint16 - RemoteIP string + LocalIP string + LocalPort uint16 + RemoteIP string RemotePort uint16 } type RecvBuffer struct { recvNext uint32 - lbr uint32 - buffer []byte + lbr uint32 + buffer []byte } type SendBuffer struct { - una uint32 - nxt uint32 - lbr uint32 + una uint32 + nxt uint32 + lbr uint32 buffer []byte } -// create a socket map +// create a socket map // var VHostSocketMaps = make(map[int]*SocketEntry) var VHostSocketMaps = make(map[SocketKey]*SocketEntry) -// create a channel map + +// create a channel map var VHostChannelMaps = make(map[int]chan []byte) var mapMutex = &sync.Mutex{} var socketsMade = 0 @@ -1263,8 +1268,8 @@ var startingSeqNum = rand.Uint32() func VListen(port uint16) (*VTCPListener, error) { myIP := GetInterfaces()[0].IpPrefix.Addr() listener := &VTCPListener{ - Socket: socketsMade, - State: Listening, + Socket: socketsMade, + State: Listening, LocalPort: port, LocalAddr: myIP.String(), } @@ -1274,12 +1279,12 @@ func VListen(port uint16) (*VTCPListener, error) { key := SocketKey{myIP.String(), port, "", 0} VHostSocketMaps[key] = &SocketEntry{ - Socket: socketsMade, - LocalIP: myIP.String(), - LocalPort: port, - RemoteIP: "0.0.0.0", + Socket: socketsMade, + LocalIP: myIP.String(), + LocalPort: port, + RemoteIP: "0.0.0.0", RemotePort: 0, - State: Listening, + State: Listening, } mapMutex.Unlock() socketsMade += 1 @@ -1289,29 +1294,29 @@ func VListen(port uint16) (*VTCPListener, error) { func (l *VTCPListener) VAccept() (*VTCPConn, error) { // synChan = make(chan bool) - for { - // wait for a SYN request + for { + // wait for a SYN request mapMutex.Lock() for _, socketEntry := range VHostSocketMaps { if socketEntry.State == Established { // create a new VTCPConn conn := &VTCPConn{ - LocalAddr: socketEntry.LocalIP, - LocalPort: socketEntry.LocalPort, + LocalAddr: socketEntry.LocalIP, + LocalPort: socketEntry.LocalPort, RemoteAddr: socketEntry.RemoteIP, RemotePort: socketEntry.RemotePort, - Socket: socketEntry.Socket, - State: Established, + Socket: socketEntry.Socket, + State: Established, SendBuffer: &SendBuffer{ - una: 0, - nxt: 0, - lbr: 0, + una: 0, + nxt: 0, + lbr: 0, buffer: make([]byte, MAX_WINDOW_SIZE), }, RecvBuffer: &RecvBuffer{ recvNext: 0, - lbr: 0, - buffer: make([]byte, MAX_WINDOW_SIZE), + lbr: 0, + buffer: make([]byte, MAX_WINDOW_SIZE), }, } socketEntry.Conn = conn @@ -1329,7 +1334,7 @@ func GetRandomPort() uint16 { minDynamicPort = 49152 maxDynamicPort = 65535 ) - return uint16(rand.Intn(maxDynamicPort - minDynamicPort) + minDynamicPort) + return uint16(rand.Intn(maxDynamicPort-minDynamicPort) + minDynamicPort) } func VConnect(ip string, port uint16) (*VTCPConn, error) { @@ -1337,16 +1342,16 @@ func VConnect(ip string, port uint16) (*VTCPConn, error) { myIP := GetInterfaces()[0].IpPrefix.Addr() // get random port portRand := GetRandomPort() - + tcpHdr := &header.TCPFields{ - SrcPort: portRand, - DstPort: port, - SeqNum: startingSeqNum, - AckNum: 0, - DataOffset: 20, - Flags: header.TCPFlagSyn, - WindowSize: MAX_WINDOW_SIZE, - Checksum: 0, + SrcPort: portRand, + DstPort: port, + SeqNum: startingSeqNum, + AckNum: 0, + DataOffset: 20, + Flags: header.TCPFlagSyn, + WindowSize: MAX_WINDOW_SIZE, + Checksum: 0, UrgentPointer: 0, } payload := []byte{} @@ -1361,22 +1366,22 @@ func VConnect(ip string, port uint16) (*VTCPConn, error) { } conn := &VTCPConn{ - LocalAddr: myIP.String(), - LocalPort: portRand, + LocalAddr: myIP.String(), + LocalPort: portRand, RemoteAddr: ip, RemotePort: port, - Socket: socketsMade, - State: Established, + Socket: socketsMade, + State: Established, SendBuffer: &SendBuffer{ - una: 0, - nxt: 0, - lbr: 0, + una: 0, + nxt: 0, + lbr: 0, buffer: make([]byte, MAX_WINDOW_SIZE), }, RecvBuffer: &RecvBuffer{ recvNext: 0, - lbr: 0, - buffer: make([]byte, MAX_WINDOW_SIZE), + lbr: 0, + buffer: make([]byte, MAX_WINDOW_SIZE), }, } @@ -1384,13 +1389,13 @@ func VConnect(ip string, port uint16) (*VTCPConn, error) { key := SocketKey{myIP.String(), portRand, ip, port} mapMutex.Lock() VHostSocketMaps[key] = &SocketEntry{ - Socket: socketsMade, - LocalIP: myIP.String(), - LocalPort: portRand, - RemoteIP: ip, + Socket: socketsMade, + LocalIP: myIP.String(), + LocalPort: portRand, + RemoteIP: ip, RemotePort: port, - State: SYNSENT, - Conn: conn, + State: SYNSENT, + Conn: conn, } mapMutex.Unlock() socketsMade += 1 @@ -1462,7 +1467,6 @@ func (c *VTCPConn) VClose() error { return nil } - // advertise window = max window size - (next - 1 - lbr) // early arrivals queue @@ -1497,21 +1501,21 @@ func (c *VTCPConn) VWrite(payload []byte) (int, error) { } // check if the payload is larger than the available window size - if len(payload) > int(MAX_WINDOW_SIZE - (c.SendBuffer.nxt - 1 - c.SendBuffer.lbr)) { + if len(payload) > int(MAX_WINDOW_SIZE-(c.SendBuffer.nxt-1-c.SendBuffer.lbr)) { return 0, errors.Errorf("error VWrite: payload is larger than the available window size") } // make the header advertisedWindow := MAX_WINDOW_SIZE - (c.SendBuffer.nxt - 1 - c.SendBuffer.lbr) tcpHdr := &header.TCPFields{ - SrcPort: c.LocalPort, - DstPort: c.RemotePort, - SeqNum: c.SendBuffer.nxt, - AckNum: c.SendBuffer.una, - DataOffset: 20, - Flags: header.TCPFlagSyn, - WindowSize: uint16(advertisedWindow), - Checksum: 0, + SrcPort: c.LocalPort, + DstPort: c.RemotePort, + SeqNum: c.SendBuffer.nxt, + AckNum: c.SendBuffer.una, + DataOffset: 20, + Flags: header.TCPFlagSyn, + WindowSize: uint16(advertisedWindow), + Checksum: 0, UrgentPointer: 0, } @@ -1528,12 +1532,10 @@ func (c *VTCPConn) VWrite(payload []byte) (int, error) { // update the next sequence number // c.SendBuffer.nxt += uint32(len(payload)) - c.SendBuffer.lbr += uint32(len(payload)) return len(payload), nil } - func (c *VTCPConn) VRead(numBytesToRead int) (int, string, error) { // check if the socket is in the map key := SocketKey{c.LocalAddr, c.LocalPort, c.RemoteAddr, c.RemotePort} @@ -1550,16 +1552,24 @@ func (c *VTCPConn) VRead(numBytesToRead int) (int, string, error) { return 0, "", errors.Errorf("error VRead: socket %d is not in established state", c.Socket) } fmt.Println("I am in VRead") - fmt.Println("I have", c.RecvBuffer.recvNext - c.RecvBuffer.lbr, "bytes to read") - fmt.Println(c.RecvBuffer.recvNext, c.RecvBuffer.lbr) - if (c.RecvBuffer.lbr < c.RecvBuffer.recvNext && c.RecvBuffer.recvNext - c.RecvBuffer.lbr >= uint32(numBytesToRead)) { + // fmt.Println("I have", c.RecvBuffer.recvNext-c.RecvBuffer.lbr, "bytes to read") + fmt.Println("recvNext", c.RecvBuffer.recvNext, "lbr", c.RecvBuffer.lbr) + var diff uint32 + if c.RecvBuffer.recvNext-c.RecvBuffer.lbr <= uint32(numBytesToRead) { + diff = c.RecvBuffer.recvNext - c.RecvBuffer.lbr + } else if c.RecvBuffer.recvNext-c.RecvBuffer.lbr > uint32(numBytesToRead) { + diff = uint32(numBytesToRead) + } else { + diff = 0 + } + if c.RecvBuffer.lbr < c.RecvBuffer.recvNext && diff != 0 { fmt.Println("I have enough data to read") - toReturn := string(socketEntry.Conn.RecvBuffer.buffer[c.RecvBuffer.lbr:c.RecvBuffer.lbr+uint32(numBytesToRead)]) + toReturn := string(socketEntry.Conn.RecvBuffer.buffer[c.RecvBuffer.lbr : c.RecvBuffer.lbr+diff]) // update the last byte read - c.RecvBuffer.lbr += uint32(numBytesToRead) + c.RecvBuffer.lbr += diff // return the data return numBytesToRead, toReturn, nil } return 0, "", nil -}
\ No newline at end of file +} Binary files differBinary files differ |