github.com/cloudwego/kitex@v0.9.0/pkg/remote/trans/listen_config.go (about) 1 //go:build !windows 2 // +build !windows 3 4 /* 5 * Copyright 2022 CloudWeGo Authors 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package trans 21 22 import ( 23 "net" 24 "syscall" 25 26 "golang.org/x/sys/unix" 27 28 "github.com/cloudwego/kitex/pkg/remote" 29 ) 30 31 // NewListenConfig return an new net.ListenConfig. 32 func NewListenConfig(opt *remote.ServerOption) net.ListenConfig { 33 return net.ListenConfig{ 34 Control: func(network, address string, c syscall.RawConn) error { 35 var err error 36 c.Control(func(fd uintptr) { 37 if !opt.ReusePort { 38 return 39 } 40 /* The real behavior of 'SO_REUSEADDR/SO_REUSEPORT' depends on the underlying OS. 41 For BSD(/Darwin): 42 With 'SO_REUSEADDR' option, the socket can be successfully bound unless there is 43 a conflict with another socket bound to exactly the same combination of source address and port. 44 45 Here is an example to give a better overview: 46 SO_REUSEADDR socketA socketB Result 47 --------------------------------------------------------------------- 48 ON/OFF 192.168.0.1:21 192.168.0.1:21 Error (EADDRINUSE) 49 ON/OFF 192.168.0.1:21 10.0.0.1:21 OK 50 ON/OFF 10.0.0.1:21 192.168.0.1:21 OK 51 OFF 0.0.0.0:21 192.168.1.0:21 Error (EADDRINUSE) 52 OFF 192.168.1.0:21 0.0.0.0:21 Error (EADDRINUSE) 53 ON 0.0.0.0:21 192.168.1.0:21 OK 54 ON 192.168.1.0:21 0.0.0.0:21 OK 55 ON/OFF 0.0.0.0:21 0.0.0.0:21 Error (EADDRINUSE) 56 57 With 'SO_REUSEPORT', you could bind an arbitrary number of sockets to exactly the same source address 58 and port as long as all prior bound sockets also had 'SO_REUSEPORT' set before they were bound. 59 For Linux < 3.9: 60 Only the option 'SO_REUSEADDR' existed. 61 For Linux >= 3.9: 62 The 'SO_REUSEPORT' behaves exactly like the option in BSD. 63 64 More details can be found at https://stackoverflow.com/questions/14388706/how-do-so-reuseaddr-and-so-reuseport-differ. 65 */ 66 if err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1); err != nil { 67 return 68 } 69 if err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil { 70 return 71 } 72 }) 73 return err 74 }, 75 } 76 }