blob: 6f75261d3d030456e350ec87fbf1b417238cae9d [file] [log] [blame]
Russ Coxe8a02232008-09-16 13:42:47 -07001// Copyright 2009 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
Rob Pike40a7db32009-11-08 15:57:25 -08005// The net package provides a portable interface to Unix
6// networks sockets, including TCP/IP, UDP, domain name
7// resolution, and Unix domain sockets.
Russ Coxe8a02232008-09-16 13:42:47 -07008package net
9
Russ Cox35ace1d2009-11-01 11:15:34 -080010// TODO(rsc):
11// support for raw IP sockets
12// support for raw ethernet sockets
Russ Coxe8a02232008-09-16 13:42:47 -070013
Russ Cox35ace1d2009-11-01 11:15:34 -080014import "os"
Russ Cox97bc2222009-05-07 17:36:29 -070015
Russ Coxc83b8382009-11-02 18:37:30 -080016// Addr represents a network end point address.
17type Addr interface {
18 Network() string; // name of the network
Robert Griesemer5d377052009-11-04 23:16:46 -080019 String() string; // string form of address
Russ Coxc83b8382009-11-02 18:37:30 -080020}
21
22// Conn is a generic stream-oriented network connection.
Russ Coxcc1d4b72009-05-13 18:03:41 -070023type Conn interface {
Russ Coxc83b8382009-11-02 18:37:30 -080024 // Read reads data from the connection.
25 // Read can be made to time out and return err == os.EAGAIN
26 // after a fixed time limit; see SetTimeout and SetReadTimeout.
Russ Coxcc1d4b72009-05-13 18:03:41 -070027 Read(b []byte) (n int, err os.Error);
28
Russ Coxc83b8382009-11-02 18:37:30 -080029 // Write writes data to the connection.
30 // Write can be made to time out and return err == os.EAGAIN
31 // after a fixed time limit; see SetTimeout and SetReadTimeout.
Russ Coxcc1d4b72009-05-13 18:03:41 -070032 Write(b []byte) (n int, err os.Error);
33
34 // Close closes the connection.
35 Close() os.Error;
36
Rob Pikeefc40882009-06-19 16:03:59 -070037 // LocalAddr returns the local network address.
Russ Coxc83b8382009-11-02 18:37:30 -080038 LocalAddr() Addr;
Rob Pikeefc40882009-06-19 16:03:59 -070039
40 // RemoteAddr returns the remote network address.
Russ Coxc83b8382009-11-02 18:37:30 -080041 RemoteAddr() Addr;
Russ Coxcc1d4b72009-05-13 18:03:41 -070042
43 // SetTimeout sets the read and write deadlines associated
44 // with the connection.
45 SetTimeout(nsec int64) os.Error;
46
47 // SetReadTimeout sets the time (in nanoseconds) that
48 // Read will wait for data before returning os.EAGAIN.
49 // Setting nsec == 0 (the default) disables the deadline.
50 SetReadTimeout(nsec int64) os.Error;
51
52 // SetWriteTimeout sets the time (in nanoseconds) that
53 // Write will wait to send its data before returning os.EAGAIN.
54 // Setting nsec == 0 (the default) disables the deadline.
55 // Even if write times out, it may return n > 0, indicating that
56 // some of the data was successfully written.
57 SetWriteTimeout(nsec int64) os.Error;
Russ Coxcc1d4b72009-05-13 18:03:41 -070058}
59
Russ Coxc83b8382009-11-02 18:37:30 -080060// PacketConn is a generic packet-oriented network connection.
61type PacketConn interface {
62 // ReadFrom reads a packet from the connection,
63 // copying the payload into b. It returns the number of
64 // bytes copied into b and the return address that
65 // was on the packet.
66 // ReadFrom can be made to time out and return err == os.EAGAIN
67 // after a fixed time limit; see SetTimeout and SetReadTimeout.
68 ReadFrom(b []byte) (n int, addr Addr, err os.Error);
69
70 // WriteTo writes a packet with payload b to addr.
71 // WriteTo can be made to time out and return err == os.EAGAIN
72 // after a fixed time limit; see SetTimeout and SetWriteTimeout.
73 // On packet-oriented connections, write timeouts are rare.
74 WriteTo(b []byte, addr Addr) (n int, err os.Error);
75
76 // Close closes the connection.
77 Close() os.Error;
78
79 // LocalAddr returns the local network address.
80 LocalAddr() Addr;
81
82 // SetTimeout sets the read and write deadlines associated
83 // with the connection.
84 SetTimeout(nsec int64) os.Error;
85
86 // SetReadTimeout sets the time (in nanoseconds) that
87 // Read will wait for data before returning os.EAGAIN.
88 // Setting nsec == 0 (the default) disables the deadline.
89 SetReadTimeout(nsec int64) os.Error;
90
91 // SetWriteTimeout sets the time (in nanoseconds) that
92 // Write will wait to send its data before returning os.EAGAIN.
93 // Setting nsec == 0 (the default) disables the deadline.
94 // Even if write times out, it may return n > 0, indicating that
95 // some of the data was successfully written.
96 SetWriteTimeout(nsec int64) os.Error;
97}
98
99// A Listener is a generic network listener for stream-oriented protocols.
Russ Cox35ace1d2009-11-01 11:15:34 -0800100// Accept waits for the next connection and Close closes the connection.
101type Listener interface {
Russ Coxc83b8382009-11-02 18:37:30 -0800102 Accept() (c Conn, err os.Error);
Russ Cox35ace1d2009-11-01 11:15:34 -0800103 Close() os.Error;
Russ Coxc83b8382009-11-02 18:37:30 -0800104 Addr() Addr; // Listener's network address
Russ Cox5d2ee9d2009-06-17 21:44:26 -0700105}
106
Russ Coxc93da7c72009-03-05 15:48:12 -0800107// Dial connects to the remote address raddr on the network net.
108// If the string laddr is not empty, it is used as the local address
109// for the connection.
110//
111// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
112// "udp", "udp4" (IPv4-only), and "udp6" (IPv6-only).
113//
114// For IP networks, addresses have the form host:port. If host is
115// a literal IPv6 address, it must be enclosed in square brackets.
116//
Russ Coxe8a02232008-09-16 13:42:47 -0700117// Examples:
118// Dial("tcp", "", "12.34.56.78:80")
Russ Coxc93da7c72009-03-05 15:48:12 -0800119// Dial("tcp", "", "google.com:80")
Russ Coxe8a02232008-09-16 13:42:47 -0700120// Dial("tcp", "", "[de:ad:be:ef::ca:fe]:80")
121// Dial("tcp", "127.0.0.1:123", "127.0.0.1:88")
Russ Coxc83b8382009-11-02 18:37:30 -0800122//
Rob Pikeaaf63f82009-04-17 00:08:24 -0700123func Dial(net, laddr, raddr string) (c Conn, err os.Error) {
Russ Coxa4f15642008-09-30 14:03:13 -0700124 switch net {
Russ Coxe8a02232008-09-16 13:42:47 -0700125 case "tcp", "tcp4", "tcp6":
Russ Coxc83b8382009-11-02 18:37:30 -0800126 var la, ra *TCPAddr;
127 if laddr != "" {
128 if la, err = ResolveTCPAddr(laddr); err != nil {
Robert Griesemer40621d52009-11-09 12:07:39 -0800129 goto Error
Russ Coxc83b8382009-11-02 18:37:30 -0800130 }
Russ Coxe8a02232008-09-16 13:42:47 -0700131 }
Russ Coxc83b8382009-11-02 18:37:30 -0800132 if raddr != "" {
133 if ra, err = ResolveTCPAddr(raddr); err != nil {
Robert Griesemer40621d52009-11-09 12:07:39 -0800134 goto Error
Russ Coxc83b8382009-11-02 18:37:30 -0800135 }
136 }
137 return DialTCP(net, la, ra);
Russ Coxe8a02232008-09-16 13:42:47 -0700138 case "udp", "udp4", "upd6":
Russ Coxc83b8382009-11-02 18:37:30 -0800139 var la, ra *UDPAddr;
140 if laddr != "" {
141 if la, err = ResolveUDPAddr(laddr); err != nil {
Robert Griesemer40621d52009-11-09 12:07:39 -0800142 goto Error
Russ Coxc83b8382009-11-02 18:37:30 -0800143 }
144 }
145 if raddr != "" {
146 if ra, err = ResolveUDPAddr(raddr); err != nil {
Robert Griesemer40621d52009-11-09 12:07:39 -0800147 goto Error
Russ Coxc83b8382009-11-02 18:37:30 -0800148 }
149 }
150 return DialUDP(net, la, ra);
151 case "unix", "unixgram":
152 var la, ra *UnixAddr;
153 if raddr != "" {
154 if ra, err = ResolveUnixAddr(net, raddr); err != nil {
Robert Griesemer40621d52009-11-09 12:07:39 -0800155 goto Error
Russ Coxc83b8382009-11-02 18:37:30 -0800156 }
157 }
158 if laddr != "" {
159 if la, err = ResolveUnixAddr(net, laddr); err != nil {
Robert Griesemer40621d52009-11-09 12:07:39 -0800160 goto Error
Russ Coxc83b8382009-11-02 18:37:30 -0800161 }
162 }
163 return DialUnix(net, la, ra);
Russ Coxe8a02232008-09-16 13:42:47 -0700164 }
Russ Coxc83b8382009-11-02 18:37:30 -0800165 err = UnknownNetworkError(net);
166Error:
167 return nil, &OpError{"dial", net+" "+raddr, nil, err};
Russ Coxe8a02232008-09-16 13:42:47 -0700168}
169
Russ Coxc93da7c72009-03-05 15:48:12 -0800170// Listen announces on the local network address laddr.
Russ Coxc83b8382009-11-02 18:37:30 -0800171// The network string net must be a stream-oriented
172// network: "tcp", "tcp4", "tcp6", or "unix".
Rob Pikeaaf63f82009-04-17 00:08:24 -0700173func Listen(net, laddr string) (l Listener, err os.Error) {
Russ Coxa4f15642008-09-30 14:03:13 -0700174 switch net {
Russ Cox9350ef42008-09-17 13:49:23 -0700175 case "tcp", "tcp4", "tcp6":
Russ Coxc83b8382009-11-02 18:37:30 -0800176 var la *TCPAddr;
177 if laddr != "" {
178 if la, err = ResolveTCPAddr(laddr); err != nil {
Robert Griesemer40621d52009-11-09 12:07:39 -0800179 return nil, err
Russ Coxc83b8382009-11-02 18:37:30 -0800180 }
181 }
182 l, err := ListenTCP(net, la);
Russ Cox9350ef42008-09-17 13:49:23 -0700183 if err != nil {
Robert Griesemer40621d52009-11-09 12:07:39 -0800184 return nil, err
Russ Cox9350ef42008-09-17 13:49:23 -0700185 }
Russ Coxcc1d4b72009-05-13 18:03:41 -0700186 return l, nil;
Russ Coxc83b8382009-11-02 18:37:30 -0800187 case "unix":
188 var la *UnixAddr;
189 if laddr != "" {
190 if la, err = ResolveUnixAddr(net, laddr); err != nil {
Robert Griesemer40621d52009-11-09 12:07:39 -0800191 return nil, err
Russ Coxc83b8382009-11-02 18:37:30 -0800192 }
193 }
194 l, err := ListenUnix(net, la);
Russ Coxcc1d4b72009-05-13 18:03:41 -0700195 if err != nil {
Robert Griesemer40621d52009-11-09 12:07:39 -0800196 return nil, err
Russ Coxcc1d4b72009-05-13 18:03:41 -0700197 }
198 return l, nil;
Russ Coxc83b8382009-11-02 18:37:30 -0800199 }
200 return nil, UnknownNetworkError(net);
201}
202
203// ListenPacket announces on the local network address laddr.
204// The network string net must be a packet-oriented network:
205// "udp", "udp4", "udp6", or "unixgram".
206func ListenPacket(net, laddr string) (c PacketConn, err os.Error) {
207 switch net {
208 case "udp", "udp4", "udp6":
209 var la *UDPAddr;
210 if laddr != "" {
211 if la, err = ResolveUDPAddr(laddr); err != nil {
Robert Griesemer40621d52009-11-09 12:07:39 -0800212 return nil, err
Russ Coxc83b8382009-11-02 18:37:30 -0800213 }
214 }
215 c, err := ListenUDP(net, la);
216 if err != nil {
Robert Griesemer40621d52009-11-09 12:07:39 -0800217 return nil, err
Russ Coxc83b8382009-11-02 18:37:30 -0800218 }
219 return c, nil;
220 case "unixgram":
221 var la *UnixAddr;
222 if laddr != "" {
223 if la, err = ResolveUnixAddr(net, laddr); err != nil {
Robert Griesemer40621d52009-11-09 12:07:39 -0800224 return nil, err
Russ Coxc83b8382009-11-02 18:37:30 -0800225 }
226 }
227 c, err := DialUnix(net, la, nil);
228 if err != nil {
Robert Griesemer40621d52009-11-09 12:07:39 -0800229 return nil, err
Russ Coxc83b8382009-11-02 18:37:30 -0800230 }
231 return c, nil;
Russ Cox9350ef42008-09-17 13:49:23 -0700232 }
Russ Coxa0bcaf42009-06-25 20:24:55 -0700233 return nil, UnknownNetworkError(net);
Russ Cox9350ef42008-09-17 13:49:23 -0700234}
Russ Cox6201a962008-09-26 14:11:26 -0700235
Russ Cox35ace1d2009-11-01 11:15:34 -0800236var errMissingAddress = os.ErrorString("missing address")
237
238type OpError struct {
Robert Griesemer5d377052009-11-04 23:16:46 -0800239 Op string;
240 Net string;
241 Addr Addr;
242 Error os.Error;
Russ Cox35ace1d2009-11-01 11:15:34 -0800243}
244
245func (e *OpError) String() string {
246 s := e.Op;
247 if e.Net != "" {
Robert Griesemer40621d52009-11-09 12:07:39 -0800248 s += " " + e.Net
Russ Cox35ace1d2009-11-01 11:15:34 -0800249 }
Russ Coxc83b8382009-11-02 18:37:30 -0800250 if e.Addr != nil {
Robert Griesemer40621d52009-11-09 12:07:39 -0800251 s += " " + e.Addr.String()
Russ Cox35ace1d2009-11-01 11:15:34 -0800252 }
253 s += ": " + e.Error.String();
254 return s;
255}
256
257type AddrError struct {
Robert Griesemer5d377052009-11-04 23:16:46 -0800258 Error string;
259 Addr string;
Russ Cox35ace1d2009-11-01 11:15:34 -0800260}
261
262func (e *AddrError) String() string {
263 s := e.Error;
264 if e.Addr != "" {
Robert Griesemer40621d52009-11-09 12:07:39 -0800265 s += " " + e.Addr
Russ Cox35ace1d2009-11-01 11:15:34 -0800266 }
267 return s;
268}
269
270type UnknownNetworkError string
Robert Griesemer5d377052009-11-04 23:16:46 -0800271
Robert Griesemer368f8cb2009-11-06 14:24:38 -0800272func (e UnknownNetworkError) String() string { return "unknown network " + string(e) }