aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsotech117 <michael_foiani@brown.edu>2023-11-08 18:02:03 -0500
committersotech117 <michael_foiani@brown.edu>2023-11-08 18:02:03 -0500
commit921dd3c38a052861d0523e775efd2f1dac45ebcc (patch)
treec614bd2cb82418ff56fb76224757778d8088961f
parenta571eee893bc308a75e66f37f908752bb1cbb321 (diff)
get basic sending and reading to work
-rw-r--r--cmd/vhost/main.go16
-rw-r--r--pkg/ipstack/ipstack.go272
-rwxr-xr-xvhostbin3181890 -> 3191006 bytes
-rwxr-xr-xvrouterbin3164418 -> 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
+}
diff --git a/vhost b/vhost
index 1ddd11e..71946eb 100755
--- a/vhost
+++ b/vhost
Binary files differ
diff --git a/vrouter b/vrouter
index 6ebcda2..707d2d0 100755
--- a/vrouter
+++ b/vrouter
Binary files differ