github.com/dubbogo/gost@v1.14.0/net/conncheck.go (about) 1 //go:build linux || darwin || dragonfly || freebsd || netbsd || openbsd || solaris || illumos 2 // +build linux darwin dragonfly freebsd netbsd openbsd solaris illumos 3 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 // Go MySQL Driver - A MySQL-Driver for Go's database/sql package 22 // 23 // Copyright 2019 The Go-MySQL-Driver Authors. All rights reserved. 24 // 25 // This Source Code Form is subject to the terms of the Mozilla Public 26 // License, v. 2.0. If a copy of the MPL was not distributed with this file, 27 // You can obtain one at http://mozilla.org/MPL/2.0/. 28 29 package gxnet 30 31 import ( 32 "errors" 33 "io" 34 "net" 35 "syscall" 36 ) 37 38 var errUnexpectedRead = errors.New("unexpected read from socket") 39 40 func ConnCheck(conn net.Conn) error { 41 var sysErr error 42 43 sysConn, ok := conn.(syscall.Conn) 44 if !ok { 45 return nil 46 } 47 rawConn, err := sysConn.SyscallConn() 48 if err != nil { 49 return err 50 } 51 52 err = rawConn.Read(func(fd uintptr) bool { 53 var buf [1]byte 54 n, readErr := syscall.Read(int(fd), buf[:]) 55 switch { 56 case n == 0 && readErr == nil: 57 sysErr = io.EOF 58 case n > 0: 59 sysErr = errUnexpectedRead 60 case readErr == syscall.EAGAIN || readErr == syscall.EWOULDBLOCK: 61 sysErr = nil 62 default: 63 sysErr = readErr 64 } 65 return true 66 }) 67 if err != nil { 68 return err 69 } 70 71 return sysErr 72 }