Output CodeView function information
[official-gcc.git] / libgo / go / net / rawconn_unix_test.go
blob7069d01b958ced8dbe4b659d6b5bee3ec0497ecd
1 // Copyright 2017 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 //go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris
7 package net
9 import (
10 "errors"
11 "syscall"
14 func readRawConn(c syscall.RawConn, b []byte) (int, error) {
15 var operr error
16 var n int
17 err := c.Read(func(s uintptr) bool {
18 n, operr = syscall.Read(int(s), b)
19 if operr == syscall.EAGAIN {
20 return false
22 return true
24 if err != nil {
25 return n, err
27 return n, operr
30 func writeRawConn(c syscall.RawConn, b []byte) error {
31 var operr error
32 err := c.Write(func(s uintptr) bool {
33 _, operr = syscall.Write(int(s), b)
34 if operr == syscall.EAGAIN {
35 return false
37 return true
39 if err != nil {
40 return err
42 return operr
45 func controlRawConn(c syscall.RawConn, addr Addr) error {
46 var operr error
47 fn := func(s uintptr) {
48 _, operr = syscall.GetsockoptInt(int(s), syscall.SOL_SOCKET, syscall.SO_REUSEADDR)
49 if operr != nil {
50 return
52 switch addr := addr.(type) {
53 case *TCPAddr:
54 // There's no guarantee that IP-level socket
55 // options work well with dual stack sockets.
56 // A simple solution would be to take a look
57 // at the bound address to the raw connection
58 // and to classify the address family of the
59 // underlying socket by the bound address:
61 // - When IP.To16() != nil and IP.To4() == nil,
62 // we can assume that the raw connection
63 // consists of an IPv6 socket using only
64 // IPv6 addresses.
66 // - When IP.To16() == nil and IP.To4() != nil,
67 // the raw connection consists of an IPv4
68 // socket using only IPv4 addresses.
70 // - Otherwise, the raw connection is a dual
71 // stack socket, an IPv6 socket using IPv6
72 // addresses including IPv4-mapped or
73 // IPv4-embedded IPv6 addresses.
74 if addr.IP.To16() != nil && addr.IP.To4() == nil {
75 operr = syscall.SetsockoptInt(int(s), syscall.IPPROTO_IPV6, syscall.IPV6_UNICAST_HOPS, 1)
76 } else if addr.IP.To16() == nil && addr.IP.To4() != nil {
77 operr = syscall.SetsockoptInt(int(s), syscall.IPPROTO_IP, syscall.IP_TTL, 1)
81 if err := c.Control(fn); err != nil {
82 return err
84 return operr
87 func controlOnConnSetup(network string, address string, c syscall.RawConn) error {
88 var operr error
89 var fn func(uintptr)
90 switch network {
91 case "tcp", "udp", "ip":
92 return errors.New("ambiguous network: " + network)
93 case "unix", "unixpacket", "unixgram":
94 fn = func(s uintptr) {
95 _, operr = syscall.GetsockoptInt(int(s), syscall.SOL_SOCKET, syscall.SO_ERROR)
97 default:
98 switch network[len(network)-1] {
99 case '4':
100 fn = func(s uintptr) {
101 operr = syscall.SetsockoptInt(int(s), syscall.IPPROTO_IP, syscall.IP_TTL, 1)
103 case '6':
104 fn = func(s uintptr) {
105 operr = syscall.SetsockoptInt(int(s), syscall.IPPROTO_IPV6, syscall.IPV6_UNICAST_HOPS, 1)
107 default:
108 return errors.New("unknown network: " + network)
111 if err := c.Control(fn); err != nil {
112 return err
114 return operr