Skip to content

Commit

Permalink
Merge pull request loxilb-io#30 from TrekkieCoder/main
Browse files Browse the repository at this point in the history
PR - Fixed probes for ep6
  • Loading branch information
TrekkieCoder authored Dec 17, 2024
2 parents c9db5d5 + 5c5ede1 commit e6e2cd3
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 39 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ require (
golang.org/x/sys v0.8.0 // indirect
)

require github.com/loxilb-io/sctp v0.0.0-20240912025756-01894eac308b
require github.com/loxilb-io/sctp v0.0.0-20241217032220-301b591b9ced
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ github.com/loxilb-io/sctp v0.0.0-20240912024735-b9c5910e672f h1:sm8UnXJa4dAV/wTE
github.com/loxilb-io/sctp v0.0.0-20240912024735-b9c5910e672f/go.mod h1:g3xKRvSWoeijv487mRGw3sLDacD9bC+wRQ4QebiafiQ=
github.com/loxilb-io/sctp v0.0.0-20240912025756-01894eac308b h1:QZHlUZTWMpghNQW/OzdKFY2PhhPFMPAjsfRSLZkAONU=
github.com/loxilb-io/sctp v0.0.0-20240912025756-01894eac308b/go.mod h1:g3xKRvSWoeijv487mRGw3sLDacD9bC+wRQ4QebiafiQ=
github.com/loxilb-io/sctp v0.0.0-20241217032220-301b591b9ced h1:XRB++1zTq2epcR8c8K+OK0+8RnEg/Rf6a73qs+rJ0fE=
github.com/loxilb-io/sctp v0.0.0-20241217032220-301b591b9ced/go.mod h1:g3xKRvSWoeijv487mRGw3sLDacD9bC+wRQ4QebiafiQ=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
Expand Down
48 changes: 17 additions & 31 deletions lib_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ package loxilib

import (
"fmt"
"net"
"testing"
"github.com/loxilb-io/sctp"
)

type Tk struct {
Expand Down Expand Up @@ -999,38 +997,19 @@ func TestIPAlloc(t *testing.T) {
}

func TestProber(t *testing.T) {
epIp, err := net.ResolveIPAddr("ip", "127.0.0.1")
if err != nil {
t.Fatal("Failed to resolve IP")
}

ips := []net.IPAddr{*epIp}
sOk := L4ServiceProber("sctp", "192.168.20.58:8080", "", "", "")
t.Logf("sctp prober test1 %v", sOk)

addr := &sctp.SCTPAddr{
IPAddrs: ips,
Port: 8080,
}

cn, err := sctp.DialSCTP("sctp", nil, addr, false)
if err == nil {
t.Logf("sctp prober connected")
cn.Close()
} else {
t.Logf("sctp prober not connected %s", err)
}
sOk = L4ServiceProber("sctp", "[3ffe:cafe::1]:1346", "", "", "")
t.Logf("sctp prober test2 %v", sOk)

cn, err = sctp.DialSCTP("sctp", nil, addr, true)
if err == nil {
t.Logf("sctp (block) prober connected")
cn.Close()
} else {
t.Logf("sctp (block) prober not connected %s", err)
}
sOk = L4ServiceProber("tcp", "192.168.20.58:8081", "", "", "")
t.Logf("tcp prober test1 %v", sOk)

// We are checking if this blocks forever
t.Logf("sctp prober test OK")
sOk = L4ServiceProber("sctp", "[3ffe:cafe::1]:1446", "", "", "")
t.Logf("tcp prober test2 %v", sOk)

sOk := L4ServiceProber("udp", "192.168.20.55:12234", "", "", "")
sOk = L4ServiceProber("udp", "192.168.20.55:12234", "", "", "")
t.Logf("udp prober test1 %v\n", sOk)

sOk = L4ServiceProber("udp", "127.0.0.1:12234", "", "", "")
Expand All @@ -1039,6 +1018,13 @@ func TestProber(t *testing.T) {
sOk = L4ServiceProber("udp", "127.0.0.1:8080", "", "", "")
t.Logf("udp prober test3 %v\n", sOk)

sOk = L4ServiceProber("udp", "[::1]:8080", "", "", "")
t.Logf("udp prober test4 %v\n", sOk)

sOk = L4ServiceProber("udp", "[3ffe:cafe::1]:2020", "", "", "")
t.Logf("udp prober test5 %v\n", sOk)

sOk = L4ServiceProber("udp", "192.168.20.55:2234", "", "", "")
t.Logf("udp prober test4 %v\n\n\n", sOk)
t.Logf("udp prober test6 %v\n", sOk)

}
65 changes: 58 additions & 7 deletions serviceprobe.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/loxilb-io/sctp"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
"net"
"net/http"
"os"
Expand Down Expand Up @@ -45,6 +46,50 @@ func waitForBoolChannelOrTimeout(ch <-chan bool, timeout time.Duration) (bool, b
}
}

func listenForICMP6UNreachable() {
conn, err := icmp.ListenPacket("ip6:ipv6-icmp", "::")
if err != nil {
os.Exit(1)
}
defer conn.Close()

buffer := make([]byte, 1500)
//conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
icmpRunner <- true
for {
n, _, err := conn.ReadFrom(buffer)
if err != nil {
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
continue // Ignore timeout errors
}
continue
}

// Parse the ICMPv6 message
message, err := icmp.ParseMessage(ipv6.ICMPTypeDestinationUnreachable.Protocol(), buffer[:n])
if err != nil {
continue
}

// Check for Destination Unreachable messages
if message.Type == ipv6.ICMPTypeDestinationUnreachable {
if body, ok := message.Body.(*icmp.DstUnreach); ok {
pktData := body.Data
if len(pktData) >= 48 {
destIP := net.IP(pktData[24:40]).String()
dport := int(pktData[42])<<8 | int(pktData[43])
svcLock.Lock()
key := SvcKey{Dst: destIP, Port: dport}
if svcWait := svcs[key]; svcWait != nil {
svcWait.wait <- true
}
svcLock.Unlock()
}
}
}
}
}

func listenForICMPUNreachable() {

// Open a raw socket to listen for ICMP messages
Expand Down Expand Up @@ -109,6 +154,8 @@ func L4ServiceProber(sType string, sName string, sHint, req, resp string) bool {
icmpRunner = make(chan bool)
svcs = map[SvcKey]*SvcWait{}
go listenForICMPUNreachable()
go listenForICMP6UNreachable()
<-icmpRunner
<-icmpRunner
}
svcLock.Unlock()
Expand All @@ -133,15 +180,14 @@ func L4ServiceProber(sType string, sName string, sHint, req, resp string) bool {
}

netAddr := sName[:len(sName)-len(portString)-1]
if netAddr[0:1] == "[" {
netAddr = strings.Trim(netAddr, "[")
netAddr = strings.Trim(netAddr, "]")
}

if sType == "sctp" {
if netAddr[0:1] == "[" {
netAddr = strings.Trim(netAddr, "[")
netAddr = strings.Trim(netAddr, "]")
}

network := "ip4"

if IsNetIPv6(netAddr) {
network = "ip6"
}
Expand Down Expand Up @@ -225,7 +271,7 @@ func L4ServiceProber(sType string, sName string, sHint, req, resp string) bool {
} else if sType == "udp" {

svcLock.Lock()
key := SvcKey{Dst: svcPair[0], Port: svcPort}
key := SvcKey{Dst: netAddr, Port: svcPort}
svcWait := svcs[key]
if svcWait == nil {
svcWait = &SvcWait{wait: make(chan bool)}
Expand All @@ -245,7 +291,12 @@ func L4ServiceProber(sType string, sName string, sHint, req, resp string) bool {
return sOk
}

_, unRch := waitForBoolChannelOrTimeout(svcWait.wait, 1*time.Second)
period := 1 * time.Second
if IsNetIPv6(netAddr) {
period = 3 * time.Second
}

_, unRch := waitForBoolChannelOrTimeout(svcWait.wait, period)
if unRch {
sOk = false
}
Expand Down

0 comments on commit e6e2cd3

Please sign in to comment.