syscallconn.go (1818B)
1 /* 2 * 3 * Copyright 2018 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package credentials 20 21 import ( 22 "net" 23 "syscall" 24 ) 25 26 type sysConn = syscall.Conn 27 28 // syscallConn keeps reference of rawConn to support syscall.Conn for channelz. 29 // SyscallConn() (the method in interface syscall.Conn) is explicitly 30 // implemented on this type, 31 // 32 // Interface syscall.Conn is implemented by most net.Conn implementations (e.g. 33 // TCPConn, UnixConn), but is not part of net.Conn interface. So wrapper conns 34 // that embed net.Conn don't implement syscall.Conn. (Side note: tls.Conn 35 // doesn't embed net.Conn, so even if syscall.Conn is part of net.Conn, it won't 36 // help here). 37 type syscallConn struct { 38 net.Conn 39 // sysConn is a type alias of syscall.Conn. It's necessary because the name 40 // `Conn` collides with `net.Conn`. 41 sysConn 42 } 43 44 // WrapSyscallConn tries to wrap rawConn and newConn into a net.Conn that 45 // implements syscall.Conn. rawConn will be used to support syscall, and newConn 46 // will be used for read/write. 47 // 48 // This function returns newConn if rawConn doesn't implement syscall.Conn. 49 func WrapSyscallConn(rawConn, newConn net.Conn) net.Conn { 50 sysConn, ok := rawConn.(syscall.Conn) 51 if !ok { 52 return newConn 53 } 54 return &syscallConn{ 55 Conn: newConn, 56 sysConn: sysConn, 57 } 58 }