Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
6e788e0f
Commit
6e788e0f
authored
Nov 17, 2009
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
net: enforce timeouts for ReadFrom/WriteTo
Fixes #153. R=r
https://golang.org/cl/154177
parent
a65bf95d
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
81 additions
and
23 deletions
+81
-23
fd.go
src/pkg/net/fd.go
+56
-0
server_test.go
src/pkg/net/server_test.go
+1
-1
timeout_test.go
src/pkg/net/timeout_test.go
+20
-6
udpsock.go
src/pkg/net/udpsock.go
+2
-8
unixsock.go
src/pkg/net/unixsock.go
+2
-8
No files found.
src/pkg/net/fd.go
View file @
6e788e0f
...
@@ -372,6 +372,33 @@ func (fd *netFD) Read(p []byte) (n int, err os.Error) {
...
@@ -372,6 +372,33 @@ func (fd *netFD) Read(p []byte) (n int, err os.Error) {
return
;
return
;
}
}
func
(
fd
*
netFD
)
ReadFrom
(
p
[]
byte
)
(
n
int
,
sa
syscall
.
Sockaddr
,
err
os
.
Error
)
{
if
fd
==
nil
||
fd
.
file
==
nil
{
return
0
,
nil
,
os
.
EINVAL
}
fd
.
rio
.
Lock
();
defer
fd
.
rio
.
Unlock
();
if
fd
.
rdeadline_delta
>
0
{
fd
.
rdeadline
=
pollserver
.
Now
()
+
fd
.
rdeadline_delta
}
else
{
fd
.
rdeadline
=
0
}
for
{
var
errno
int
;
n
,
sa
,
errno
=
syscall
.
Recvfrom
(
fd
.
fd
,
p
,
0
);
if
errno
==
syscall
.
EAGAIN
&&
fd
.
rdeadline
>=
0
{
pollserver
.
WaitRead
(
fd
);
continue
;
}
if
errno
!=
0
{
n
=
0
;
err
=
&
os
.
PathError
{
"recvfrom"
,
fd
.
file
.
Name
(),
os
.
Errno
(
errno
)};
}
break
;
}
return
;
}
func
(
fd
*
netFD
)
Write
(
p
[]
byte
)
(
n
int
,
err
os
.
Error
)
{
func
(
fd
*
netFD
)
Write
(
p
[]
byte
)
(
n
int
,
err
os
.
Error
)
{
if
fd
==
nil
||
fd
.
file
==
nil
{
if
fd
==
nil
||
fd
.
file
==
nil
{
return
0
,
os
.
EINVAL
return
0
,
os
.
EINVAL
...
@@ -404,6 +431,35 @@ func (fd *netFD) Write(p []byte) (n int, err os.Error) {
...
@@ -404,6 +431,35 @@ func (fd *netFD) Write(p []byte) (n int, err os.Error) {
return
nn
,
err
;
return
nn
,
err
;
}
}
func
(
fd
*
netFD
)
WriteTo
(
p
[]
byte
,
sa
syscall
.
Sockaddr
)
(
n
int
,
err
os
.
Error
)
{
if
fd
==
nil
||
fd
.
file
==
nil
{
return
0
,
os
.
EINVAL
}
fd
.
wio
.
Lock
();
defer
fd
.
wio
.
Unlock
();
if
fd
.
wdeadline_delta
>
0
{
fd
.
wdeadline
=
pollserver
.
Now
()
+
fd
.
wdeadline_delta
}
else
{
fd
.
wdeadline
=
0
}
err
=
nil
;
for
{
errno
:=
syscall
.
Sendto
(
fd
.
fd
,
p
,
0
,
sa
);
if
errno
==
syscall
.
EAGAIN
&&
fd
.
wdeadline
>=
0
{
pollserver
.
WaitWrite
(
fd
);
continue
;
}
if
errno
!=
0
{
err
=
&
os
.
PathError
{
"sendto"
,
fd
.
file
.
Name
(),
os
.
Errno
(
errno
)}
}
break
;
}
if
err
==
nil
{
n
=
len
(
p
)
}
return
;
}
func
(
fd
*
netFD
)
accept
(
toAddr
func
(
syscall
.
Sockaddr
)
Addr
)
(
nfd
*
netFD
,
err
os
.
Error
)
{
func
(
fd
*
netFD
)
accept
(
toAddr
func
(
syscall
.
Sockaddr
)
Addr
)
(
nfd
*
netFD
,
err
os
.
Error
)
{
if
fd
==
nil
||
fd
.
file
==
nil
{
if
fd
==
nil
||
fd
.
file
==
nil
{
return
nil
,
os
.
EINVAL
return
nil
,
os
.
EINVAL
...
...
src/pkg/net/server_test.go
View file @
6e788e0f
...
@@ -116,7 +116,7 @@ func runPacket(t *testing.T, network, addr string, listening chan<- string, done
...
@@ -116,7 +116,7 @@ func runPacket(t *testing.T, network, addr string, listening chan<- string, done
var
buf
[
1000
]
byte
;
var
buf
[
1000
]
byte
;
for
{
for
{
n
,
addr
,
err
:=
c
.
ReadFrom
(
&
buf
);
n
,
addr
,
err
:=
c
.
ReadFrom
(
&
buf
);
if
err
==
os
.
EAGAIN
{
if
isEAGAIN
(
err
)
{
if
done
<-
1
{
if
done
<-
1
{
break
break
}
}
...
...
src/pkg/net/timeout_test.go
View file @
6e788e0f
...
@@ -5,11 +5,12 @@
...
@@ -5,11 +5,12 @@
package
net
package
net
import
(
import
(
"os"
;
"testing"
;
"testing"
;
"time"
;
"time"
;
)
)
func
testTimeout
(
t
*
testing
.
T
,
network
,
addr
string
)
{
func
testTimeout
(
t
*
testing
.
T
,
network
,
addr
string
,
readFrom
bool
)
{
fd
,
err
:=
Dial
(
network
,
""
,
addr
);
fd
,
err
:=
Dial
(
network
,
""
,
addr
);
defer
fd
.
Close
();
defer
fd
.
Close
();
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -18,21 +19,34 @@ func testTimeout(t *testing.T, network, addr string) {
...
@@ -18,21 +19,34 @@ func testTimeout(t *testing.T, network, addr string) {
t0
:=
time
.
Nanoseconds
();
t0
:=
time
.
Nanoseconds
();
fd
.
SetReadTimeout
(
1e8
);
// 100ms
fd
.
SetReadTimeout
(
1e8
);
// 100ms
var
b
[
100
]
byte
;
var
b
[
100
]
byte
;
n
,
err1
:=
fd
.
Read
(
&
b
);
var
n
int
;
var
err1
os
.
Error
;
if
readFrom
{
n
,
_
,
err1
=
fd
.
(
PacketConn
)
.
ReadFrom
(
&
b
)
}
else
{
n
,
err1
=
fd
.
Read
(
&
b
)
}
t1
:=
time
.
Nanoseconds
();
t1
:=
time
.
Nanoseconds
();
what
:=
"Read"
;
if
readFrom
{
what
=
"ReadFrom"
}
if
n
!=
0
||
!
isEAGAIN
(
err1
)
{
if
n
!=
0
||
!
isEAGAIN
(
err1
)
{
t
.
Errorf
(
"fd.
Read on %s %s did not return 0, EAGAIN: %v, %v"
,
network
,
addr
,
n
,
err1
)
t
.
Errorf
(
"fd.
%s on %s %s did not return 0, EAGAIN: %v, %v"
,
what
,
network
,
addr
,
n
,
err1
)
}
}
if
t1
-
t0
<
0.5e8
||
t1
-
t0
>
1.5e8
{
if
t1
-
t0
<
0.5e8
||
t1
-
t0
>
1.5e8
{
t
.
Errorf
(
"fd.
Read on %s %s took %f seconds, expected 0.1"
,
network
,
addr
,
float64
(
t1
-
t0
)
/
1e9
)
t
.
Errorf
(
"fd.
%s on %s %s took %f seconds, expected 0.1"
,
what
,
network
,
addr
,
float64
(
t1
-
t0
)
/
1e9
)
}
}
}
}
func
TestTimeoutUDP
(
t
*
testing
.
T
)
{
testTimeout
(
t
,
"udp"
,
"127.0.0.1:53"
)
}
func
TestTimeoutUDP
(
t
*
testing
.
T
)
{
testTimeout
(
t
,
"udp"
,
"127.0.0.1:53"
,
false
);
testTimeout
(
t
,
"udp"
,
"127.0.0.1:53"
,
true
);
}
func
TestTimeoutTCP
(
t
*
testing
.
T
)
{
func
TestTimeoutTCP
(
t
*
testing
.
T
)
{
// 74.125.19.99 is www.google.com.
// 74.125.19.99 is www.google.com.
// could use dns, but dns depends on
// could use dns, but dns depends on
// timeouts and this is the timeout test.
// timeouts and this is the timeout test.
testTimeout
(
t
,
"tcp"
,
"74.125.19.99:80"
)
testTimeout
(
t
,
"tcp"
,
"74.125.19.99:80"
,
false
)
}
}
src/pkg/net/udpsock.go
View file @
6e788e0f
...
@@ -188,10 +188,7 @@ func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err os.Error) {
...
@@ -188,10 +188,7 @@ func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err os.Error) {
if
!
c
.
ok
()
{
if
!
c
.
ok
()
{
return
0
,
nil
,
os
.
EINVAL
return
0
,
nil
,
os
.
EINVAL
}
}
n
,
sa
,
errno
:=
syscall
.
Recvfrom
(
c
.
fd
.
fd
,
b
,
0
);
n
,
sa
,
err
:=
c
.
fd
.
ReadFrom
(
b
);
if
errno
!=
0
{
err
=
os
.
Errno
(
errno
)
}
switch
sa
:=
sa
.
(
type
)
{
switch
sa
:=
sa
.
(
type
)
{
case
*
syscall
.
SockaddrInet4
:
case
*
syscall
.
SockaddrInet4
:
addr
=
&
UDPAddr
{
&
sa
.
Addr
,
sa
.
Port
}
addr
=
&
UDPAddr
{
&
sa
.
Addr
,
sa
.
Port
}
...
@@ -228,10 +225,7 @@ func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (n int, err os.Error) {
...
@@ -228,10 +225,7 @@ func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (n int, err os.Error) {
if
err
!=
nil
{
if
err
!=
nil
{
return
0
,
err
return
0
,
err
}
}
if
errno
:=
syscall
.
Sendto
(
c
.
fd
.
fd
,
b
,
0
,
sa
);
errno
!=
0
{
return
c
.
fd
.
WriteTo
(
b
,
sa
);
return
0
,
os
.
Errno
(
errno
)
}
return
len
(
b
),
nil
;
}
}
// WriteTo writes a UDP packet with payload b to addr via c.
// WriteTo writes a UDP packet with payload b to addr via c.
...
...
src/pkg/net/unixsock.go
View file @
6e788e0f
...
@@ -243,10 +243,7 @@ func (c *UnixConn) ReadFromUnix(b []byte) (n int, addr *UnixAddr, err os.Error)
...
@@ -243,10 +243,7 @@ func (c *UnixConn) ReadFromUnix(b []byte) (n int, addr *UnixAddr, err os.Error)
if
!
c
.
ok
()
{
if
!
c
.
ok
()
{
return
0
,
nil
,
os
.
EINVAL
return
0
,
nil
,
os
.
EINVAL
}
}
n
,
sa
,
errno
:=
syscall
.
Recvfrom
(
c
.
fd
.
fd
,
b
,
0
);
n
,
sa
,
err
:=
c
.
fd
.
ReadFrom
(
b
);
if
errno
!=
0
{
err
=
os
.
Errno
(
errno
)
}
switch
sa
:=
sa
.
(
type
)
{
switch
sa
:=
sa
.
(
type
)
{
case
*
syscall
.
SockaddrUnix
:
case
*
syscall
.
SockaddrUnix
:
addr
=
&
UnixAddr
{
sa
.
Name
,
c
.
fd
.
proto
==
syscall
.
SOCK_DGRAM
}
addr
=
&
UnixAddr
{
sa
.
Name
,
c
.
fd
.
proto
==
syscall
.
SOCK_DGRAM
}
...
@@ -281,10 +278,7 @@ func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (n int, err os.Error) {
...
@@ -281,10 +278,7 @@ func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (n int, err os.Error) {
return
0
,
os
.
EAFNOSUPPORT
return
0
,
os
.
EAFNOSUPPORT
}
}
sa
:=
&
syscall
.
SockaddrUnix
{
Name
:
addr
.
Name
};
sa
:=
&
syscall
.
SockaddrUnix
{
Name
:
addr
.
Name
};
if
errno
:=
syscall
.
Sendto
(
c
.
fd
.
fd
,
b
,
0
,
sa
);
errno
!=
0
{
return
c
.
fd
.
WriteTo
(
b
,
sa
);
return
0
,
os
.
Errno
(
errno
)
}
return
len
(
b
),
nil
;
}
}
// WriteTo writes a packet to addr via c, copying the payload from b.
// WriteTo writes a packet to addr via c, copying the payload from b.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment