Skip to content

Commit 9e9c14d

Browse files
fix getSysConn to work with TLS (#918)
`tls.Conn` by default doesn't implement `syscall.Conn` and hence tchannel emits `onnection does not implement SyscallConn.` log a lot. Since go 1.18, `tls.Conn` exposes method `NetConn()` to expose raw underlying TCP connection. This is used for getting the `syscall.Conn`.
1 parent 49a0061 commit 9e9c14d

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

connection.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
package tchannel
2222

2323
import (
24+
"crypto/tls"
2425
"errors"
2526
"fmt"
2627
"io"
@@ -971,7 +972,18 @@ func (c *Connection) getLastActivityWriteTime() time.Time {
971972
}
972973

973974
func getSysConn(conn net.Conn, log Logger) syscall.RawConn {
974-
connSyscall, ok := conn.(syscall.Conn)
975+
var (
976+
connSyscall syscall.Conn
977+
ok bool
978+
)
979+
switch v := conn.(type) {
980+
case syscall.Conn:
981+
connSyscall = v
982+
ok = true
983+
case *tls.Conn:
984+
connSyscall, ok = v.NetConn().(syscall.Conn)
985+
}
986+
975987
if !ok {
976988
log.WithFields(LogField{"connectionType", fmt.Sprintf("%T", conn)}).
977989
Error("Connection does not implement SyscallConn.")

connection_internal_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ package tchannel
2222

2323
import (
2424
"bytes"
25+
"crypto/tls"
2526
"net"
27+
"net/http/httptest"
2628
"syscall"
2729
"testing"
2830

@@ -79,4 +81,45 @@ func TestGetSysConn(t *testing.T) {
7981
require.NotNil(t, sysConn)
8082
assert.Empty(t, loggerBuf.String(), "expected no logs on success")
8183
})
84+
85+
t.Run("SyscallConn is successful with TLS", func(t *testing.T) {
86+
var (
87+
loggerBuf = &bytes.Buffer{}
88+
logger = NewLogger(loggerBuf)
89+
server = httptest.NewTLSServer(nil)
90+
)
91+
defer server.Close()
92+
93+
conn, err := tls.Dial("tcp", server.Listener.Addr().String(), &tls.Config{InsecureSkipVerify: true})
94+
require.NoError(t, err, "failed to dial")
95+
defer conn.Close()
96+
97+
sysConn := getSysConn(conn, logger)
98+
require.NotNil(t, sysConn)
99+
assert.Empty(t, loggerBuf.String(), "expected no logs on success")
100+
})
101+
102+
t.Run("no SyscallConn - nil net.Conn", func(t *testing.T) {
103+
var (
104+
loggerBuf = &bytes.Buffer{}
105+
logger = NewLogger(loggerBuf)
106+
syscallConn = getSysConn(nil /* conn */, logger)
107+
)
108+
109+
require.Nil(t, syscallConn, "expected no syscall.RawConn to be returned")
110+
assert.Contains(t, loggerBuf.String(), "Connection does not implement SyscallConn", "missing log")
111+
assert.Contains(t, loggerBuf.String(), "{connectionType <nil>}", "missing type in log")
112+
})
113+
114+
t.Run("no SyscallConn - TLS with no net.Conn", func(t *testing.T) {
115+
var (
116+
loggerBuf = &bytes.Buffer{}
117+
logger = NewLogger(loggerBuf)
118+
syscallConn = getSysConn(&tls.Conn{}, logger)
119+
)
120+
121+
require.Nil(t, syscallConn, "expected no syscall.RawConn to be returned")
122+
assert.Contains(t, loggerBuf.String(), "Connection does not implement SyscallConn", "missing log")
123+
assert.Contains(t, loggerBuf.String(), "{connectionType *tls.Conn}", "missing type in log")
124+
})
82125
}

0 commit comments

Comments
 (0)