Change:
How to repro: an agnhost pod listening on sctp into the pod and use the connect command to probe against the same pod The stack trace that points to and this is from the vendored library , /kind bug /sig network /help
This request has been marked as needing help from a contributor. Please ensure that the issue body includes answers to the following questions: Why are we solving this issue? To address this issue, are there any code changes? If there are code changes, what needs to be done in the code and what places can the assignee treat as reference points? Does this issue have zero to low barrier of entry? How can the assignee reach out to you for help? For more details on the requirements of such an issue, please see and ensure that they are met. If this request no longer meets these requirements, the label can be removed by commenting with the command. <detailsIn response to : Run an agnhost pod listening on sctpExec into the pod and use the connect command to probe against the same pod The stack trace that points to /sig network /help </details
/assign
/triage accepted
here we are immediately closing the connection after successful connect leading to EOF at server end (it is expecting data) causing the failure. We can tweak this to connect send some data just like UDP and then exit? Works locally writing "hostname" to the connection. [EDIT] For me it sometimes failed with EOF, sometime with nil pointer exception at . This reads sock opts via syscall and we immediately close the connection .. kind of a race between the client closing connection and server reading fds?
the panic seems a bug in that project, no? Also SCTP, has a establishment handshake, so the data should not be relevant in this case
returns fd and socket address, for is used to implement (always read from struct field). The SCTP implementation discards the returned socket address by call. , and is always a new syscall (). In our case the client immediately closes the connection, there can be chances where SCTPGETPEERADDRS will fail and will return nil in these cases. I think this is reasonable for their project. We call and panic is raised by calling on nil object. We can easily avoid this by not null check. Also, I strongly believe that the client handling should be done in a separate go-routine instead of the main loop to avoid errors like this crashing the pod. [EDIT] The client in our case needs to send some data after connection, or else the server will throw EOF and we currently have assertions that use for errors.
panicing does not seem very reasonable It looks to me that the problem is that the SCTPConn struct needs to check if the connection is still valid before trying to access the file descriptor , see the std library implementation and then, all methods implement this check to me it is a bug on the implementation
The implementation is not causing any panic, it simply returns nil. Panic is caused when we try to call on nil object.
oh, sorry, my bad I should read your comment with more detail, is well explained there I recognize I have zero idea of how sctp works internally, maybe we can just be more resilient on our tests and code and detect if is nil and avoid getting into the complexity of this protocol ... sending some random data also sounds good, we do this for udp IIRC
are you able to send a PR to add those improvements to the test image?

Discussion:
<del> 2.49 </del> <ins> 2.50 </ins>

timeout  time.Duration protocol string udpData  string <ins> sctpData string </ins> ) func init() { CmdConnect.Flags().DurationVar(&timeout, "timeout", time.Duration(0), "Maximum time before returning an error") CmdConnect.Flags().StringVar(&protocol, "protocol", "tcp", "The protocol to use to perform the connection, can be tcp, udp or sctp") CmdConnect.Flags().StringVar(&udpData, "udp-data", "hostname", "The UDP payload send to the server") <ins> CmdConnect.Flags().StringVar(&sctpData, "sctp-data", "hostname", "The SCTP payload send to the server") </ins> } func main(cmd *cobra.Command, args []string) {

case "udp": connectUDP(dest, timeout, udpData) case "sctp": <del> connectSCTP(dest, timeout) </del> <ins> connectSCTP(dest, timeout, sctpData) </ins> default: fmt.Fprint(os.Stderr, "Unsupported protocoln", protocol) os.Exit(1)

os.Exit(1) } <del> func connectSCTP(dest string, timeout time.Duration) { </del> <ins> func connectSCTP(dest string, timeout time.Duration, data string) { var ( buf  = make([]byte, 1024) conn *sctp.SCTPConn ) </ins> addr, err := sctp.ResolveSCTPAddr("sctp", dest) if err != nil { fmt.Fprintf(os.Stderr, "DNS: %vn", err)

errCh := make(chan error) go func() { <del> conn, err := sctp.DialSCTP("sctp", nil, addr) if err == nil { conn.Close() </del> <ins> conn, err = sctp.DialSCTP("sctp", nil, addr) if err != nil { errCh <- err return } defer func() { errCh <- conn.Close() }() if _, err = conn.Write([]byte(fmt.Sprintf("%sn", data))); err != nil { errCh <- err return } if _, err = conn.Read(buf); err != nil { errCh <- err return </ins> } <del> errCh <- err </del> }() select {

for { conn, err := listener.AcceptSCTP() assertNoError(err, fmt.Sprintf("failed accepting SCTP connections")) <del> clientAddress := conn.RemoteAddr().String() </del> <ins> remoteAddr, err := conn.SCTPRemoteAddr(0) if err != nil { assertNoError(err, "failed to get SCTP client remote address") } clientAddress := remoteAddr.String() </ins> n, err := conn.Read(buf) assertNoError(err, fmt.Sprintf("failed to read from SCTP client %s", clientAddress)) receivedText := strings.ToLower(strings.TrimSpace(string(buf[0:n])))