1
1
package internet
2
2
3
3
import (
4
- network "net"
4
+ gonet "net"
5
5
"os"
6
6
"syscall"
7
7
"unsafe"
@@ -108,14 +108,6 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf
108
108
return err
109
109
}
110
110
}
111
- if config .Interface != "" {
112
- InterfaceIndex := getInterfaceIndexByName (config .Interface )
113
- if InterfaceIndex != 0 {
114
- if err := unix .SetsockoptInt (int (fd ), syscall .IPPROTO_IP , syscall .IP_BOUND_IF , InterfaceIndex ); err != nil {
115
- return errors .New ("failed to set Interface" ).Base (err )
116
- }
117
- }
118
- }
119
111
120
112
if config .TcpKeepAliveIdle > 0 || config .TcpKeepAliveInterval > 0 {
121
113
if config .TcpKeepAliveIdle > 0 {
@@ -138,6 +130,23 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf
138
130
}
139
131
}
140
132
133
+ if config .Interface != "" {
134
+ iface , err := gonet .InterfaceByName (config .Interface )
135
+
136
+ if err != nil {
137
+ return errors .New ("failed to get interface " , config .Interface ).Base (err )
138
+ }
139
+ if network == "tcp6" || network == "udp6" {
140
+ if err := unix .SetsockoptInt (int (fd ), unix .IPPROTO_IPV6 , unix .IPV6_BOUND_IF , iface .Index ); err != nil {
141
+ return errors .New ("failed to set IPV6_BOUND_IF" ).Base (err )
142
+ }
143
+ } else {
144
+ if err := unix .SetsockoptInt (int (fd ), unix .IPPROTO_IP , unix .IP_BOUND_IF , iface .Index ); err != nil {
145
+ return errors .New ("failed to set IP_BOUND_IF" ).Base (err )
146
+ }
147
+ }
148
+ }
149
+
141
150
return nil
142
151
}
143
152
@@ -152,14 +161,6 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig)
152
161
return err
153
162
}
154
163
}
155
- if config .Interface != "" {
156
- InterfaceIndex := getInterfaceIndexByName (config .Interface )
157
- if InterfaceIndex != 0 {
158
- if err := unix .SetsockoptInt (int (fd ), syscall .IPPROTO_IP , syscall .IP_BOUND_IF , InterfaceIndex ); err != nil {
159
- return errors .New ("failed to set Interface" ).Base (err )
160
- }
161
- }
162
- }
163
164
164
165
if config .TcpKeepAliveIdle > 0 || config .TcpKeepAliveInterval > 0 {
165
166
if config .TcpKeepAliveIdle > 0 {
@@ -182,6 +183,23 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig)
182
183
}
183
184
}
184
185
186
+ if config .Interface != "" {
187
+ iface , err := gonet .InterfaceByName (config .Interface )
188
+
189
+ if err != nil {
190
+ return errors .New ("failed to get interface " , config .Interface ).Base (err )
191
+ }
192
+ if network == "tcp6" || network == "udp6" {
193
+ if err := unix .SetsockoptInt (int (fd ), unix .IPPROTO_IPV6 , unix .IPV6_BOUND_IF , iface .Index ); err != nil {
194
+ return errors .New ("failed to set IPV6_BOUND_IF" ).Base (err )
195
+ }
196
+ } else {
197
+ if err := unix .SetsockoptInt (int (fd ), unix .IPPROTO_IP , unix .IP_BOUND_IF , iface .Index ); err != nil {
198
+ return errors .New ("failed to set IP_BOUND_IF" ).Base (err )
199
+ }
200
+ }
201
+ }
202
+
185
203
return nil
186
204
}
187
205
@@ -224,24 +242,3 @@ func setReusePort(fd uintptr) error {
224
242
}
225
243
return nil
226
244
}
227
- func getInterfaceIndexByName (name string ) int {
228
- ifaces , err := network .Interfaces ()
229
- if err == nil {
230
- for _ , iface := range ifaces {
231
- if (iface .Flags & network .FlagUp == network .FlagUp ) && (iface .Flags & network .FlagLoopback != network .FlagLoopback ) {
232
- addrs , _ := iface .Addrs ()
233
- for _ , addr := range addrs {
234
- if ipnet , ok := addr .(* network.IPNet ); ok && ! ipnet .IP .IsLoopback () {
235
- if ipnet .IP .To4 () != nil {
236
- if iface .Name == name {
237
- return iface .Index
238
- }
239
- }
240
- }
241
- }
242
- }
243
-
244
- }
245
- }
246
- return 0
247
- }
0 commit comments