github.com/Psiphon-Inc/goarista@v0.0.0-20160825065156-d002785f4c67/dscp/listen_unix.go (about) 1 // Copyright (C) 2016 Arista Networks, Inc. 2 // Use of this source code is governed by the Apache License 2.0 3 // that can be found in the COPYING file. 4 5 package dscp 6 7 import ( 8 "net" 9 "os" 10 "reflect" 11 12 "golang.org/x/sys/unix" 13 ) 14 15 func listenTCPWithTOS(address *net.TCPAddr, tos byte) (*net.TCPListener, error) { 16 lsnr, err := net.ListenTCP("tcp", address) 17 if err != nil { 18 return nil, err 19 } 20 // This works for the UNIX implementation of netFD, i.e. not on Windows and Plan9. 21 // This kludge is needed until https://github.com/golang/go/issues/9661 is fixed. 22 fd := int(reflect.ValueOf(lsnr).Elem().FieldByName("fd").Elem().FieldByName("sysfd").Int()) 23 var proto, optname int 24 if address.IP.To4() != nil { 25 proto = unix.IPPROTO_IP 26 optname = unix.IP_TOS 27 } else { 28 proto = unix.IPPROTO_IPV6 29 optname = unix.IPV6_TCLASS 30 } 31 err = unix.SetsockoptInt(fd, proto, optname, int(tos)) 32 if err != nil { 33 lsnr.Close() 34 return nil, os.NewSyscallError("setsockopt", err) 35 } 36 37 return lsnr, nil 38 }