aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsotech117 <michael_foiani@brown.edu>2023-10-23 03:42:05 -0400
committersotech117 <michael_foiani@brown.edu>2023-10-23 03:42:05 -0400
commit512c4c2785e6dbf53106b5a6f60e0e1992977016 (patch)
tree284ede052af9a1efc2a962d7da6f9abde588b7ac
parent7ec4f310ec01100f648a42dd52cb0ac635ac0b10 (diff)
add RIP request and reponse
-rw-r--r--cmd/vhost/main.go9
-rw-r--r--cmd/vrouter/main.go4
-rw-r--r--pkg/ipstack/ipstack.go130
-rwxr-xr-xvhostbin3104785 -> 3104388 bytes
-rwxr-xr-xvrouterbin3104857 -> 3104404 bytes
5 files changed, 88 insertions, 55 deletions
diff --git a/cmd/vhost/main.go b/cmd/vhost/main.go
index 17b4a02..468409d 100644
--- a/cmd/vhost/main.go
+++ b/cmd/vhost/main.go
@@ -58,14 +58,21 @@ func main() {
messageToSendBytes := []byte(messageToSend)
hop, err := ipstack.LongestPrefix(netip.MustParseAddr(ipAddr))
+ if err != nil {
+ fmt.Println(err)
+ continue
+ }
myAddr := hop.Interface.IpPrefix.Addr()
for _, neighbor := range ipstack.GetNeighbors()[hop.Interface.Name] {
// TODO: fix multiple send bug here on static route
if neighbor.VipAddr == netip.MustParseAddr(ipAddr) ||
neighbor.VipAddr == hop.VIP && hop.Type == "S" {
- err = ipstack.SendIP(&myAddr, neighbor, ipstack.TEST_PROTOCOL, messageToSendBytes, ipAddr, nil)
+ bytesWritten, err := ipstack.SendIP(&myAddr, neighbor, ipstack.TEST_PROTOCOL, messageToSendBytes, ipAddr, nil)
if err != nil {
fmt.Println(err)
+ } else {
+ fmt.Printf("Sent %d bytes to %s\n", bytesWritten, neighbor.VipAddr.String())
+
}
}
}
diff --git a/cmd/vrouter/main.go b/cmd/vrouter/main.go
index aacf786..7998e5d 100644
--- a/cmd/vrouter/main.go
+++ b/cmd/vrouter/main.go
@@ -80,9 +80,11 @@ func main() {
for _, neighbor := range ipstack.GetNeighbors()[hop.Interface.Name] {
if neighbor.VipAddr == netip.MustParseAddr(ipAddr) ||
neighbor.VipAddr == hop.VIP {
- err = ipstack.SendIP(&myAddr, neighbor, ipstack.TEST_PROTOCOL, messageToSendBytes, ipAddr, nil)
+ bytesWritten, err := ipstack.SendIP(&myAddr, neighbor, ipstack.TEST_PROTOCOL, messageToSendBytes, ipAddr, nil)
if err != nil {
fmt.Println(err)
+ } else {
+ fmt.Printf("Sent %d bytes to %s\n", bytesWritten, neighbor.VipAddr.String())
}
}
}
diff --git a/pkg/ipstack/ipstack.go b/pkg/ipstack/ipstack.go
index 8983ef8..2116403 100644
--- a/pkg/ipstack/ipstack.go
+++ b/pkg/ipstack/ipstack.go
@@ -68,7 +68,7 @@ var myVIP Interface
var myInterfaces []*Interface
var myNeighbors = make(map[string][]*Neighbor)
-var myRIPNeighbors = make(map[string]bool)
+var myRIPNeighbors = make(map[string]*Neighbor)
type HandlerFunc func(src *Interface, dest *Neighbor, message []byte, hdr *ipv4header.IPv4Header) error
@@ -141,7 +141,7 @@ func Initialize(lnxFilePath string) error {
for _, iface := range myInterfaces {
for _, neighbor := range myNeighbors[iface.Name] {
if neighbor.VipAddr == route {
- myRIPNeighbors[neighbor.VipAddr.String()] = true
+ myRIPNeighbors[neighbor.VipAddr.String()] = neighbor
break
}
}
@@ -383,7 +383,7 @@ func CleanUp() {
}
// TODO: have it take TTL so we can decrement it when forwarding
-func SendIP(src *netip.Addr, dest *Neighbor, protocolNum int, message []byte, destIP string, hdr *ipv4header.IPv4Header) error {
+func SendIP(src *netip.Addr, dest *Neighbor, protocolNum int, message []byte, destIP string, hdr *ipv4header.IPv4Header) (int, error) {
if hdr == nil {
hdr = &ipv4header.IPv4Header{
Version: 4,
@@ -421,7 +421,7 @@ func SendIP(src *netip.Addr, dest *Neighbor, protocolNum int, message []byte, de
// Assemble the header into a byte array
headerBytes, err := hdr.Marshal()
if err != nil {
- return err
+ return -1, err
}
// Compute the checksum (see below)
@@ -442,7 +442,7 @@ func SendIP(src *netip.Addr, dest *Neighbor, protocolNum int, message []byte, de
// tmpConn, err := net.DialUDP("udp4", nil, sendAddr)
// get the interface of this neighbor
if err != nil {
- return errors.WithMessage(err, "Could not bind to UDP port->\t"+dest.UdpAddr.String())
+ return -1, errors.WithMessage(err, "Could not bind to UDP port->\t"+dest.UdpAddr.String())
}
// bytesWritten, err := tmpConn.Write(bytesToSend)
@@ -451,12 +451,10 @@ func SendIP(src *netip.Addr, dest *Neighbor, protocolNum int, message []byte, de
bytesWritten, err := iface.RecvSocket.WriteToUDP(bytesToSend, sendAddr)
if err != nil {
fmt.Println("Error writing to UDP socket")
- return errors.WithMessage(err, "Error writing to UDP socket")
+ return -1, errors.WithMessage(err, "Error writing to UDP socket")
}
- fmt.Printf("Sent %d bytes to %s\n", bytesWritten, dest.VipAddr.String())
-
- return nil
+ return bytesWritten, nil
}
func RecvIP(iface *Interface, isOpen *bool) error {
@@ -517,20 +515,20 @@ func RecvIP(iface *Interface, isOpen *bool) error {
// check if the checksum is valid
if checksumState == "FAIL" {
// drop the packet
- fmt.Println("checksum failed, dropping packet")
+ // fmt.Println("checksum failed, dropping packet")
return nil
}
// at this point, the packet is valid. next steps consider the forwarding of the packet
// 2) check if the message is for me, if so, sendUP (aka call the correct handler)
if hdr.Protocol != RIP_PROTOCOL {
- fmt.Println("I see a non-rip packet")
+ // fmt.Println("I see a non-rip packet")
}
if hdr.Dst == prefix.Addr() {
// see if there is a handler for this protocol
if handler, ok := protocolHandlers[hdr.Protocol]; ok {
if hdr.Protocol != RIP_PROTOCOL {
- fmt.Println("this test packet is exactly for me")
+ // fmt.Println("this test packet is exactly for me")
}
err := handler(iface, nil, message, hdr)
if err != nil {
@@ -543,10 +541,10 @@ func RecvIP(iface *Interface, isOpen *bool) error {
// 4) check forwarding table.
// if it's a local hop, send to that iface
// if it's a RIP hop, send to the neighbor with that VIP
- fmt.Println("checking routing table")
+ // fmt.Println("checking routing table")
hop, err := LongestPrefix(hdr.Dst)
if err == nil { // on no err, found a match
- fmt.Println("found route", hop.VIP)
+ // fmt.Println("found route", hop.VIP)
if hop.Type == "S" {
// default, static route
// drop in this case
@@ -558,7 +556,7 @@ func RecvIP(iface *Interface, isOpen *bool) error {
// if it's a local route, then the name is the interface name
for _, neighbor := range myNeighbors[hop.Interface.Name] {
if neighbor.VipAddr == hdr.Dst {
- err2 := SendIP(&hdr.Src, neighbor, hdr.Protocol, message, hdr.Dst.String(), hdr)
+ _, err2 := SendIP(&hdr.Src, neighbor, hdr.Protocol, message, hdr.Dst.String(), hdr)
if err2 != nil {
return err2
}
@@ -571,7 +569,7 @@ func RecvIP(iface *Interface, isOpen *bool) error {
// if it's a rip route, then the check is against the hop vip
for _, neighbor := range myNeighbors[hop.Interface.Name] {
if neighbor.VipAddr == hop.VIP {
- err2 := SendIP(&hdr.Src, neighbor, hdr.Protocol, message, hdr.Dst.String(), hdr)
+ _, err2 := SendIP(&hdr.Src, neighbor, hdr.Protocol, message, hdr.Dst.String(), hdr)
if err2 != nil {
return err2
}
@@ -627,10 +625,10 @@ func periodicUpdateRoutine() {
// TODO: consider making this multithreaded and loops above more efficient
// if we're here, we are sending this to a rip neighbor
- entries := make([]RIPEntry, len(routingTable))
+ entries := make([]RIPEntry, 0)
for prefix, hop := range routingTable {
// implement split horizon + poison reverse at entry level
- fmt.Println("prefix: ", prefix)
+ // fmt.Println("prefix: ", prefix)
var cost uint32
if hop.VIP == n.VipAddr {
cost = INFINITY
@@ -646,7 +644,7 @@ func periodicUpdateRoutine() {
message := makeRipMessage(2, entries)
addr := iface.IpPrefix.Addr()
- err := SendIP(&addr, n, RIP_PROTOCOL, message, n.VipAddr.String(), nil)
+ _, err := SendIP(&addr, n, RIP_PROTOCOL, message, n.VipAddr.String(), nil)
if err != nil {
fmt.Printf("Error sending RIP message to %s\n", n.VipAddr.String())
continue
@@ -667,22 +665,34 @@ func manageTimeoutsRoutine() {
for {
time.Sleep(time.Second)
- wg := &sync.WaitGroup{}
- wg.Add(len(timeoutTable))
+ // note: waitgroup causes deadlock then crashing
+ //wg := &sync.WaitGroup{}
+ //wg.Add(len(timeoutTable))
+ //mu.Lock()
+ //for prefix, _ := range timeoutTable {
+ // go func(p netip.Prefix) {
+ // timeoutTable[p]++
+ // if timeoutTable[p] == MAX_TIMEOUT {
+ // delete(routingTable, p)
+ // delete(timeoutTable, p)
+ // // TODO: send triggered update
+ // }
+ //
+ // wg.Done()
+ // }(prefix)
+ //}
+ //wg.Wait()
+ //mu.Unlock()
+
mu.Lock()
for prefix, _ := range timeoutTable {
- go func(p netip.Prefix) {
- timeoutTable[p]++
- if timeoutTable[p] == MAX_TIMEOUT {
- delete(routingTable, p)
- delete(timeoutTable, p)
- // TODO: send triggered update
- }
-
- wg.Done()
- }(prefix)
+ timeoutTable[prefix]++
+ if timeoutTable[prefix] == MAX_TIMEOUT {
+ delete(routingTable, prefix)
+ delete(timeoutTable, prefix)
+ // TODO: send triggered update
+ }
}
- wg.Wait()
mu.Unlock()
// fmt.Println("Timeout table: ", timeoutTable)
@@ -701,7 +711,7 @@ func startRipRoutines() {
// send a request
message := makeRipMessage(1, nil)
addr := iface.IpPrefix.Addr()
- err := SendIP(&addr, neighbor, RIP_PROTOCOL, message, neighbor.VipAddr.String(), nil)
+ _, err := SendIP(&addr, neighbor, RIP_PROTOCOL, message, neighbor.VipAddr.String(), nil)
if err != nil {
return
}
@@ -738,15 +748,44 @@ func handleRIP(src *Interface, dest *Neighbor, message []byte, hdr *ipv4header.I
command := int(binary.BigEndian.Uint16(message[0:2]))
switch command {
case 1:
- // request
- // SendUpdates()
+ //fmt.Println("Received RIP command for specific info")
+ // only send if the person asking is a RIP neighbor
+ neighbor, in := myRIPNeighbors[hdr.Src.String()]
+ if !in {
+ break
+ }
+
+ // fmt.Println("he is my rip neighbor ", hdr.Src.String())
+
+ // build the entries
+ entries := make([]RIPEntry, 0)
+ for prefix, hop := range routingTable {
+ // implement split horizon + poison reverse at entry level
+ // fmt.Println("prefix: ", prefix)
+ var cost uint32
+ if hop.VIP == hdr.Src {
+ cost = INFINITY
+ } else {
+ cost = hop.Cost
+ }
+ entries = append(entries,
+ RIPEntry{
+ prefix: prefix,
+ cost: cost,
+ })
+ }
+ res := makeRipMessage(2, nil)
+ _, err := SendIP(&hdr.Dst, neighbor, RIP_PROTOCOL, res, hdr.Src.String(), nil)
+ if err != nil {
+ return err
+ }
break
case 2:
numEntries := int(binary.BigEndian.Uint16(message[2:4]))
- fmt.Println("Received RIP response with", numEntries, "entries")
+ // fmt.Println("Received RIP response with", numEntries, "entries")
// parse the entries
- entries := make([]RIPEntry, 0, numEntries)
+ entries := make([]RIPEntry, 0)
for i := 0; i < numEntries; i++ {
offset := SIZE_OF_RIP_HEADER + i*SIZE_OF_RIP_ENTRY
@@ -762,7 +801,7 @@ func handleRIP(src *Interface, dest *Neighbor, message []byte, hdr *ipv4header.I
prefix := netip.PrefixFrom(address, 24)
entries = append(entries, RIPEntry{prefix, cost})
- fmt.Println("Received RIP update: ", prefix.String(), cost)
+ // fmt.Println("Received RIP update: ", prefix.String(), cost)
}
// add to routing table
@@ -1026,21 +1065,6 @@ func LongestPrefix(src netip.Addr) (Hop, error) {
// }
//}
-func ifaceContainsIP(iface Interface, ip netip.Addr) bool {
- // check if the ip is in the interface's prefix
- if iface.IpPrefix.Contains(netip.MustParseAddr(ip.String())) {
- return true
- }
- return false
-}
-
-func ConvertIPToUint32(ip string) uint32 {
- netIP := net.ParseIP(ip)
- ipBytes := netIP.To4()
- ipUint32 := uint32(ipBytes[0])<<24 | uint32(ipBytes[1])<<16 | uint32(ipBytes[2])<<8 | uint32(ipBytes[3])
- return ipUint32
-}
-
// TODO @ MICHEAL: Handle links going down and link recovery
// func CheckAndUpdateRoutingTable() {
// for {
diff --git a/vhost b/vhost
index 633b625..aa6346f 100755
--- a/vhost
+++ b/vhost
Binary files differ
diff --git a/vrouter b/vrouter
index bb36ec9..0dc05d1 100755
--- a/vrouter
+++ b/vrouter
Binary files differ