Skip to content

Commit 0072d8a

Browse files
authored
Merge pull request kubernetes#90797 from fedepaol/sctpconnectporter
Add SCTP support to agnhost connect / porter commands.
2 parents db8a887 + b8819b9 commit 0072d8a

File tree

9 files changed

+132
-36
lines changed

9 files changed

+132
-36
lines changed

test/images/agnhost/README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ Usage:
8888

8989
### connect
9090

91-
Tries to open a TCP connection to the given host and port. On error it
91+
Tries to open a TCP or SCTP connection to the given host and port. On error it
9292
prints an error message prefixed with a specific fixed string that
9393
test cases can check for:
9494

@@ -105,9 +105,11 @@ output than to check the exit code.)
105105
Usage:
106106

107107
```console
108-
kubectl exec test-agnost -- /agnost connect [--timeout=<duration>] <host>:<port>
108+
kubectl exec test-agnhost -- /agnhost connect [--timeout=<duration>] [--protocol=<protocol>] <host>:<port>
109109
```
110110

111+
The optional `--protocol` parameter can be set to `sctp` to test SCTP
112+
connections. The default value is `tcp`.
111113

112114
### crd-conversion-webhook
113115

@@ -543,10 +545,10 @@ Usage:
543545

544546
### porter
545547

546-
Serves requested data on ports specified in ENV variables. For example, if the environment
547-
variable `SERVE_PORT_9001` is set, then the subcommand will start serving on the port 9001.
548-
Additionally, if the environment variable `SERVE_TLS_PORT_9002` is set, then the subcommand
549-
will start a TLS server on that port.
548+
Serves requested data on ports specified in environment variables of the form `SERVE_{PORT,TLS_PORT,SCTP_PORT}_[NNNN]`. eg:
549+
- `SERVE_PORT_9001` - serve TCP connections on port 9001
550+
- `SERVE_TLS_PORT_9002` - serve TLS-encrypted TCP connections on port 9002
551+
- `SERVE_SCTP_PORT_9003` - serve SCTP connections on port 9003
550552

551553
The included `localhost.crt` is a PEM-encoded TLS cert with SAN IPs `127.0.0.1` and `[::1]`,
552554
expiring in January 2084, generated from `src/crypto/tls`:

test/images/agnhost/connect/BUILD

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ go_library(
99
name = "go_default_library",
1010
srcs = ["connect.go"],
1111
importpath = "k8s.io/kubernetes/test/images/agnhost/connect",
12-
deps = ["//vendor/github.com/spf13/cobra:go_default_library"],
12+
deps = [
13+
"//vendor/github.com/ishidawataru/sctp:go_default_library",
14+
"//vendor/github.com/spf13/cobra:go_default_library",
15+
],
1316
)
1417

1518
filegroup(

test/images/agnhost/connect/connect.go

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@ import (
2323
"syscall"
2424
"time"
2525

26+
"github.com/ishidawataru/sctp"
2627
"github.com/spf13/cobra"
2728
)
2829

2930
// CmdConnect is used by agnhost Cobra.
3031
var CmdConnect = &cobra.Command{
3132
Use: "connect [host:port]",
32-
Short: "Attempts a TCP connection and returns useful errors",
33-
Long: `Tries to open a TCP connection to the given host and port. On error it prints an error message prefixed with a specific fixed string that test cases can check for:
33+
Short: "Attempts a TCP or SCTP connection and returns useful errors",
34+
Long: `Tries to open a TCP or SCTP connection to the given host and port. On error it prints an error message prefixed with a specific fixed string that test cases can check for:
3435
3536
* UNKNOWN - Generic/unknown (non-network) error (eg, bad arguments)
3637
* TIMEOUT - The connection attempt timed out
@@ -42,14 +43,27 @@ var CmdConnect = &cobra.Command{
4243
}
4344

4445
var timeout time.Duration
46+
var protocol string
4547

4648
func init() {
4749
CmdConnect.Flags().DurationVar(&timeout, "timeout", time.Duration(0), "Maximum time before returning an error")
50+
CmdConnect.Flags().StringVar(&protocol, "protocol", "tcp", "The protocol to use to perform the connection, can be tcp or sctp")
4851
}
4952

5053
func main(cmd *cobra.Command, args []string) {
5154
dest := args[0]
55+
switch protocol {
56+
case "", "tcp":
57+
connectTCP(dest, timeout)
58+
case "sctp":
59+
connectSCTP(dest, timeout)
60+
default:
61+
fmt.Fprint(os.Stderr, "Unsupported protocol\n", protocol)
62+
os.Exit(1)
63+
}
64+
}
5265

66+
func connectTCP(dest string, timeout time.Duration) {
5367
// Redundantly parse and resolve the destination so we can return the correct
5468
// errors if there's a problem.
5569
if _, _, err := net.SplitHostPort(dest); err != nil {
@@ -81,3 +95,33 @@ func main(cmd *cobra.Command, args []string) {
8195
fmt.Fprintf(os.Stderr, "OTHER: %v\n", err)
8296
os.Exit(1)
8397
}
98+
99+
func connectSCTP(dest string, timeout time.Duration) {
100+
addr, err := sctp.ResolveSCTPAddr("sctp", dest)
101+
if err != nil {
102+
fmt.Fprintf(os.Stderr, "DNS: %v\n", err)
103+
os.Exit(1)
104+
}
105+
106+
timeoutCh := time.After(timeout)
107+
errCh := make(chan (error))
108+
109+
go func() {
110+
conn, err := sctp.DialSCTP("sctp", nil, addr)
111+
if err == nil {
112+
conn.Close()
113+
}
114+
errCh <- err
115+
}()
116+
117+
select {
118+
case err := <-errCh:
119+
if err != nil {
120+
fmt.Fprintf(os.Stderr, "OTHER: %v\n", err)
121+
os.Exit(1)
122+
}
123+
case <-timeoutCh:
124+
fmt.Fprint(os.Stderr, "TIMEOUT\n")
125+
os.Exit(1)
126+
}
127+
}

test/images/agnhost/porter/BUILD

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ go_library(
99
name = "go_default_library",
1010
srcs = ["porter.go"],
1111
importpath = "k8s.io/kubernetes/test/images/agnhost/porter",
12-
deps = ["//vendor/github.com/spf13/cobra:go_default_library"],
12+
deps = [
13+
"//vendor/github.com/ishidawataru/sctp:go_default_library",
14+
"//vendor/github.com/spf13/cobra:go_default_library",
15+
],
1316
)
1417

1518
filegroup(

test/images/agnhost/porter/porter.go

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,24 @@ import (
2929
"os"
3030
"strings"
3131

32+
"github.com/ishidawataru/sctp"
3233
"github.com/spf13/cobra"
3334
)
3435

35-
const prefix = "SERVE_PORT_"
36+
const tcpPrefix = "SERVE_PORT_"
37+
const sctpPrefix = "SERVE_SCTP_PORT_"
3638
const tlsPrefix = "SERVE_TLS_PORT_"
3739

3840
// CmdPorter is used by agnhost Cobra.
3941
var CmdPorter = &cobra.Command{
4042
Use: "porter",
4143
Short: "Serves requested data on ports specified in ENV variables",
42-
Long: `Serves requested data on ports specified in ENV variables. For example, if the environment variable "SERVE_PORT_9001" is set, then the subcommand will start serving on the port 9001.
43-
44-
Additionally, if the environment variable "SERVE_TLS_PORT_9002" is set, then the subcommand will start a TLS server on that port.
44+
Long: `Serves requested data on ports specified in environment variables of the form SERVE_{PORT,TLS_PORT,SCTP_PORT}_[NNNN].
45+
46+
eg:
47+
* SERVE_PORT_9001 - serve TCP connections on port 9001
48+
* SERVE_TLS_PORT_9002 - serve TLS-encrypted TCP connections on port 9002
49+
* SERVE_SCTP_PORT_9003 - serve SCTP connections on port 9003
4550
4651
The included "localhost.crt" is a PEM-encoded TLS cert with SAN IPs "127.0.0.1" and "[::1]", expiring in January 2084, generated from "src/crypto/tls".
4752
@@ -58,11 +63,15 @@ func main(cmd *cobra.Command, args []string) {
5863
parts := strings.SplitN(vk, "=", 2)
5964
key := parts[0]
6065
value := parts[1]
61-
if strings.HasPrefix(key, prefix) {
62-
port := strings.TrimPrefix(key, prefix)
66+
67+
switch {
68+
case strings.HasPrefix(key, tcpPrefix):
69+
port := strings.TrimPrefix(key, tcpPrefix)
6370
go servePort(port, value)
64-
}
65-
if strings.HasPrefix(key, tlsPrefix) {
71+
case strings.HasPrefix(key, sctpPrefix):
72+
port := strings.TrimPrefix(key, sctpPrefix)
73+
go serveSCTPPort(port, value)
74+
case strings.HasPrefix(key, tlsPrefix):
6675
port := strings.TrimPrefix(key, tlsPrefix)
6776
go serveTLSPort(port, value)
6877
}
@@ -98,3 +107,38 @@ func serveTLSPort(port, value string) {
98107
}
99108
log.Printf("tls server on port %q with certFile=%q, keyFile=%q failed: %v", port, certFile, keyFile, s.ListenAndServeTLS(certFile, keyFile))
100109
}
110+
111+
func serveSCTPPort(port, value string) {
112+
serverAddress, err := sctp.ResolveSCTPAddr("sctp", "0.0.0.0:"+port)
113+
if err != nil {
114+
log.Fatal("Sctp: failed to resolve address. error:", err)
115+
}
116+
117+
listener, err := sctp.ListenSCTP("sctp", serverAddress)
118+
if err != nil {
119+
log.Fatal("Failed to listen SCTP. error:", err)
120+
}
121+
log.Printf("Started SCTP server")
122+
123+
defer listener.Close()
124+
defer func() {
125+
log.Printf("SCTP server exited")
126+
}()
127+
128+
for {
129+
conn, err := listener.AcceptSCTP()
130+
if err != nil {
131+
log.Fatal("Failed to accept SCTP. error:", err)
132+
}
133+
go func(conn *sctp.SCTPConn) {
134+
defer conn.Close()
135+
log.Println("Sending response")
136+
_, err = conn.Write([]byte(value))
137+
if err != nil {
138+
log.Println("Failed to send response", err)
139+
return
140+
}
141+
log.Println("Response sent")
142+
}(conn)
143+
}
144+
}

test/images/kitten/BASEIMAGE

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
linux/amd64=REGISTRY/agnhost:2.19-linux-amd64
2-
linux/arm=REGISTRY/agnhost:2.19-linux-arm
3-
linux/arm64=REGISTRY/agnhost:2.19-linux-arm64
4-
linux/ppc64le=REGISTRY/agnhost:2.19-linux-ppc64le
5-
linux/s390x=REGISTRY/agnhost:2.19-linux-s390x
6-
windows/amd64/1809=REGISTRY/agnhost:2.19-windows-amd64-1809
7-
windows/amd64/1903=REGISTRY/agnhost:2.19-windows-amd64-1903
8-
windows/amd64/1909=REGISTRY/agnhost:2.19-windows-amd64-1909
1+
linux/amd64=REGISTRY/agnhost:2.20-linux-amd64
2+
linux/arm=REGISTRY/agnhost:2.20-linux-arm
3+
linux/arm64=REGISTRY/agnhost:2.20-linux-arm64
4+
linux/ppc64le=REGISTRY/agnhost:2.20-linux-ppc64le
5+
linux/s390x=REGISTRY/agnhost:2.20-linux-s390x
6+
windows/amd64/1809=REGISTRY/agnhost:2.20-windows-amd64-1809
7+
windows/amd64/1903=REGISTRY/agnhost:2.20-windows-amd64-1903
8+
windows/amd64/1909=REGISTRY/agnhost:2.20-windows-amd64-1909

test/images/kitten/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.2
1+
1.3

test/images/nautilus/BASEIMAGE

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
linux/amd64=REGISTRY/agnhost:2.19-linux-amd64
2-
linux/arm=REGISTRY/agnhost:2.19-linux-arm
3-
linux/arm64=REGISTRY/agnhost:2.19-linux-arm64
4-
linux/ppc64le=REGISTRY/agnhost:2.19-linux-ppc64le
5-
linux/s390x=REGISTRY/agnhost:2.19-linux-s390x
6-
windows/amd64/1809=REGISTRY/agnhost:2.19-windows-amd64-1809
7-
windows/amd64/1903=REGISTRY/agnhost:2.19-windows-amd64-1903
8-
windows/amd64/1909=REGISTRY/agnhost:2.19-windows-amd64-1909
1+
linux/amd64=REGISTRY/agnhost:2.20-linux-amd64
2+
linux/arm=REGISTRY/agnhost:2.20-linux-arm
3+
linux/arm64=REGISTRY/agnhost:2.20-linux-arm64
4+
linux/ppc64le=REGISTRY/agnhost:2.20-linux-ppc64le
5+
linux/s390x=REGISTRY/agnhost:2.20-linux-s390x
6+
windows/amd64/1809=REGISTRY/agnhost:2.20-windows-amd64-1809
7+
windows/amd64/1903=REGISTRY/agnhost:2.20-windows-amd64-1903
8+
windows/amd64/1909=REGISTRY/agnhost:2.20-windows-amd64-1909

test/images/nautilus/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.2
1+
1.3

0 commit comments

Comments
 (0)