github.com/psiphon-labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/UDPConn_bind.go (about) 1 // +build !windows 2 3 /* 4 * Copyright (c) 2018, Psiphon Inc. 5 * All rights reserved. 6 * 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * 20 */ 21 22 package psiphon 23 24 import ( 25 "net" 26 "os" 27 "syscall" 28 29 "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors" 30 ) 31 32 func newUDPConn(domain int, config *DialConfig) (net.PacketConn, error) { 33 34 // TODO: use https://golang.org/pkg/net/#Dialer.Control, introduced in Go 1.11? 35 36 socketFD, err := syscall.Socket(domain, syscall.SOCK_DGRAM, 0) 37 if err != nil { 38 return nil, errors.Trace(err) 39 } 40 41 syscall.CloseOnExec(socketFD) 42 43 setAdditionalSocketOptions(socketFD) 44 45 if config.DeviceBinder != nil { 46 _, err = config.DeviceBinder.BindToDevice(socketFD) 47 if err != nil { 48 syscall.Close(socketFD) 49 return nil, errors.Tracef("BindToDevice failed: %s", err) 50 } 51 } 52 53 // Convert the socket fd to a net.PacketConn 54 // This code block is from: 55 // https://github.com/golang/go/issues/6966 56 57 file := os.NewFile(uintptr(socketFD), "") 58 conn, err := net.FilePacketConn(file) // net.FilePackateConn() dups socketFD 59 file.Close() // file.Close() closes socketFD 60 if err != nil { 61 return nil, errors.Trace(err) 62 } 63 64 return conn, nil 65 }