endpoint.go (4983B)
1 // Copyright 2012 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. 4 5 package ipv4 6 7 import ( 8 "net" 9 "time" 10 11 "golang.org/x/net/internal/socket" 12 ) 13 14 // BUG(mikio): On Windows, the JoinSourceSpecificGroup, 15 // LeaveSourceSpecificGroup, ExcludeSourceSpecificGroup and 16 // IncludeSourceSpecificGroup methods of PacketConn and RawConn are 17 // not implemented. 18 19 // A Conn represents a network endpoint that uses the IPv4 transport. 20 // It is used to control basic IP-level socket options such as TOS and 21 // TTL. 22 type Conn struct { 23 genericOpt 24 } 25 26 type genericOpt struct { 27 *socket.Conn 28 } 29 30 func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil } 31 32 // NewConn returns a new Conn. 33 func NewConn(c net.Conn) *Conn { 34 cc, _ := socket.NewConn(c) 35 return &Conn{ 36 genericOpt: genericOpt{Conn: cc}, 37 } 38 } 39 40 // A PacketConn represents a packet network endpoint that uses the 41 // IPv4 transport. It is used to control several IP-level socket 42 // options including multicasting. It also provides datagram based 43 // network I/O methods specific to the IPv4 and higher layer protocols 44 // such as UDP. 45 type PacketConn struct { 46 genericOpt 47 dgramOpt 48 payloadHandler 49 } 50 51 type dgramOpt struct { 52 *socket.Conn 53 } 54 55 func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil } 56 57 // SetControlMessage sets the per packet IP-level socket options. 58 func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error { 59 if !c.payloadHandler.ok() { 60 return errInvalidConn 61 } 62 return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on) 63 } 64 65 // SetDeadline sets the read and write deadlines associated with the 66 // endpoint. 67 func (c *PacketConn) SetDeadline(t time.Time) error { 68 if !c.payloadHandler.ok() { 69 return errInvalidConn 70 } 71 return c.payloadHandler.PacketConn.SetDeadline(t) 72 } 73 74 // SetReadDeadline sets the read deadline associated with the 75 // endpoint. 76 func (c *PacketConn) SetReadDeadline(t time.Time) error { 77 if !c.payloadHandler.ok() { 78 return errInvalidConn 79 } 80 return c.payloadHandler.PacketConn.SetReadDeadline(t) 81 } 82 83 // SetWriteDeadline sets the write deadline associated with the 84 // endpoint. 85 func (c *PacketConn) SetWriteDeadline(t time.Time) error { 86 if !c.payloadHandler.ok() { 87 return errInvalidConn 88 } 89 return c.payloadHandler.PacketConn.SetWriteDeadline(t) 90 } 91 92 // Close closes the endpoint. 93 func (c *PacketConn) Close() error { 94 if !c.payloadHandler.ok() { 95 return errInvalidConn 96 } 97 return c.payloadHandler.PacketConn.Close() 98 } 99 100 // NewPacketConn returns a new PacketConn using c as its underlying 101 // transport. 102 func NewPacketConn(c net.PacketConn) *PacketConn { 103 cc, _ := socket.NewConn(c.(net.Conn)) 104 p := &PacketConn{ 105 genericOpt: genericOpt{Conn: cc}, 106 dgramOpt: dgramOpt{Conn: cc}, 107 payloadHandler: payloadHandler{PacketConn: c, Conn: cc}, 108 } 109 return p 110 } 111 112 // A RawConn represents a packet network endpoint that uses the IPv4 113 // transport. It is used to control several IP-level socket options 114 // including IPv4 header manipulation. It also provides datagram 115 // based network I/O methods specific to the IPv4 and higher layer 116 // protocols that handle IPv4 datagram directly such as OSPF, GRE. 117 type RawConn struct { 118 genericOpt 119 dgramOpt 120 packetHandler 121 } 122 123 // SetControlMessage sets the per packet IP-level socket options. 124 func (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error { 125 if !c.packetHandler.ok() { 126 return errInvalidConn 127 } 128 return setControlMessage(c.dgramOpt.Conn, &c.packetHandler.rawOpt, cf, on) 129 } 130 131 // SetDeadline sets the read and write deadlines associated with the 132 // endpoint. 133 func (c *RawConn) SetDeadline(t time.Time) error { 134 if !c.packetHandler.ok() { 135 return errInvalidConn 136 } 137 return c.packetHandler.IPConn.SetDeadline(t) 138 } 139 140 // SetReadDeadline sets the read deadline associated with the 141 // endpoint. 142 func (c *RawConn) SetReadDeadline(t time.Time) error { 143 if !c.packetHandler.ok() { 144 return errInvalidConn 145 } 146 return c.packetHandler.IPConn.SetReadDeadline(t) 147 } 148 149 // SetWriteDeadline sets the write deadline associated with the 150 // endpoint. 151 func (c *RawConn) SetWriteDeadline(t time.Time) error { 152 if !c.packetHandler.ok() { 153 return errInvalidConn 154 } 155 return c.packetHandler.IPConn.SetWriteDeadline(t) 156 } 157 158 // Close closes the endpoint. 159 func (c *RawConn) Close() error { 160 if !c.packetHandler.ok() { 161 return errInvalidConn 162 } 163 return c.packetHandler.IPConn.Close() 164 } 165 166 // NewRawConn returns a new RawConn using c as its underlying 167 // transport. 168 func NewRawConn(c net.PacketConn) (*RawConn, error) { 169 cc, err := socket.NewConn(c.(net.Conn)) 170 if err != nil { 171 return nil, err 172 } 173 r := &RawConn{ 174 genericOpt: genericOpt{Conn: cc}, 175 dgramOpt: dgramOpt{Conn: cc}, 176 packetHandler: packetHandler{IPConn: c.(*net.IPConn), Conn: cc}, 177 } 178 so, ok := sockOpts[ssoHeaderPrepend] 179 if !ok { 180 return nil, errNotImplemented 181 } 182 if err := so.SetInt(r.dgramOpt.Conn, boolint(true)); err != nil { 183 return nil, err 184 } 185 return r, nil 186 }