Skip to content

Commit e6c5779

Browse files
author
Eric Reed
committed
IPv6 support for UDP and TCP.
1 parent 42f3f06 commit e6c5779

File tree

9 files changed

+877
-131
lines changed

9 files changed

+877
-131
lines changed

src/libstd/rt/io/net/tcp.rs

Lines changed: 200 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ mod test {
148148
}
149149

150150
#[test]
151-
fn smoke_test() {
151+
fn smoke_test_ip4() {
152152
do run_in_newsched_task {
153153
let addr = next_test_ip4();
154154

@@ -168,7 +168,27 @@ mod test {
168168
}
169169

170170
#[test]
171-
fn read_eof() {
171+
fn smoke_test_ip6() {
172+
do run_in_newsched_task {
173+
let addr = next_test_ip6();
174+
175+
do spawntask_immediately {
176+
let mut listener = TcpListener::bind(addr);
177+
let mut stream = listener.accept();
178+
let mut buf = [0];
179+
stream.read(buf);
180+
assert!(buf[0] == 99);
181+
}
182+
183+
do spawntask_immediately {
184+
let mut stream = TcpStream::connect(addr);
185+
stream.write([99]);
186+
}
187+
}
188+
}
189+
190+
#[test]
191+
fn read_eof_ip4() {
172192
do run_in_newsched_task {
173193
let addr = next_test_ip4();
174194

@@ -188,7 +208,27 @@ mod test {
188208
}
189209

190210
#[test]
191-
fn read_eof_twice() {
211+
fn read_eof_ip6() {
212+
do run_in_newsched_task {
213+
let addr = next_test_ip6();
214+
215+
do spawntask_immediately {
216+
let mut listener = TcpListener::bind(addr);
217+
let mut stream = listener.accept();
218+
let mut buf = [0];
219+
let nread = stream.read(buf);
220+
assert!(nread.is_none());
221+
}
222+
223+
do spawntask_immediately {
224+
let _stream = TcpStream::connect(addr);
225+
// Close
226+
}
227+
}
228+
}
229+
230+
#[test]
231+
fn read_eof_twice_ip4() {
192232
do run_in_newsched_task {
193233
let addr = next_test_ip4();
194234

@@ -210,7 +250,29 @@ mod test {
210250
}
211251

212252
#[test]
213-
fn write_close() {
253+
fn read_eof_twice_ip6() {
254+
do run_in_newsched_task {
255+
let addr = next_test_ip6();
256+
257+
do spawntask_immediately {
258+
let mut listener = TcpListener::bind(addr);
259+
let mut stream = listener.accept();
260+
let mut buf = [0];
261+
let nread = stream.read(buf);
262+
assert!(nread.is_none());
263+
let nread = stream.read(buf);
264+
assert!(nread.is_none());
265+
}
266+
267+
do spawntask_immediately {
268+
let _stream = TcpStream::connect(addr);
269+
// Close
270+
}
271+
}
272+
}
273+
274+
#[test]
275+
fn write_close_ip4() {
214276
do run_in_newsched_task {
215277
let addr = next_test_ip4();
216278

@@ -239,7 +301,36 @@ mod test {
239301
}
240302

241303
#[test]
242-
fn multiple_connect_serial() {
304+
fn write_close_ip6() {
305+
do run_in_newsched_task {
306+
let addr = next_test_ip6();
307+
308+
do spawntask_immediately {
309+
let mut listener = TcpListener::bind(addr);
310+
let mut stream = listener.accept();
311+
let buf = [0];
312+
loop {
313+
let mut stop = false;
314+
do io_error::cond.trap(|e| {
315+
// NB: ECONNRESET on linux, EPIPE on mac
316+
assert!(e.kind == ConnectionReset || e.kind == BrokenPipe);
317+
stop = true;
318+
}).in {
319+
stream.write(buf);
320+
}
321+
if stop { break }
322+
}
323+
}
324+
325+
do spawntask_immediately {
326+
let _stream = TcpStream::connect(addr);
327+
// Close
328+
}
329+
}
330+
}
331+
332+
#[test]
333+
fn multiple_connect_serial_ip4() {
243334
do run_in_newsched_task {
244335
let addr = next_test_ip4();
245336
let max = 10;
@@ -264,7 +355,32 @@ mod test {
264355
}
265356

266357
#[test]
267-
fn multiple_connect_interleaved_greedy_schedule() {
358+
fn multiple_connect_serial_ip6() {
359+
do run_in_newsched_task {
360+
let addr = next_test_ip6();
361+
let max = 10;
362+
363+
do spawntask_immediately {
364+
let mut listener = TcpListener::bind(addr);
365+
for max.times {
366+
let mut stream = listener.accept();
367+
let mut buf = [0];
368+
stream.read(buf);
369+
assert_eq!(buf[0], 99);
370+
}
371+
}
372+
373+
do spawntask_immediately {
374+
for max.times {
375+
let mut stream = TcpStream::connect(addr);
376+
stream.write([99]);
377+
}
378+
}
379+
}
380+
}
381+
382+
#[test]
383+
fn multiple_connect_interleaved_greedy_schedule_ip4() {
268384
do run_in_newsched_task {
269385
let addr = next_test_ip4();
270386
static MAX: int = 10;
@@ -303,7 +419,46 @@ mod test {
303419
}
304420

305421
#[test]
306-
fn multiple_connect_interleaved_lazy_schedule() {
422+
fn multiple_connect_interleaved_greedy_schedule_ip6() {
423+
do run_in_newsched_task {
424+
let addr = next_test_ip6();
425+
static MAX: int = 10;
426+
427+
do spawntask_immediately {
428+
let mut listener = TcpListener::bind(addr);
429+
for int::range(0, MAX) |i| {
430+
let stream = Cell::new(listener.accept());
431+
rtdebug!("accepted");
432+
// Start another task to handle the connection
433+
do spawntask_immediately {
434+
let mut stream = stream.take();
435+
let mut buf = [0];
436+
stream.read(buf);
437+
assert!(buf[0] == i as u8);
438+
rtdebug!("read");
439+
}
440+
}
441+
}
442+
443+
connect(0, addr);
444+
445+
fn connect(i: int, addr: IpAddr) {
446+
if i == MAX { return }
447+
448+
do spawntask_immediately {
449+
rtdebug!("connecting");
450+
let mut stream = TcpStream::connect(addr);
451+
// Connect again before writing
452+
connect(i + 1, addr);
453+
rtdebug!("writing");
454+
stream.write([i as u8]);
455+
}
456+
}
457+
}
458+
}
459+
460+
#[test]
461+
fn multiple_connect_interleaved_lazy_schedule_ip4() {
307462
do run_in_newsched_task {
308463
let addr = next_test_ip4();
309464
static MAX: int = 10;
@@ -340,5 +495,43 @@ mod test {
340495
}
341496
}
342497
}
498+
#[test]
499+
fn multiple_connect_interleaved_lazy_schedule_ip6() {
500+
do run_in_newsched_task {
501+
let addr = next_test_ip6();
502+
static MAX: int = 10;
503+
504+
do spawntask_immediately {
505+
let mut listener = TcpListener::bind(addr);
506+
for int::range(0, MAX) |_| {
507+
let stream = Cell::new(listener.accept());
508+
rtdebug!("accepted");
509+
// Start another task to handle the connection
510+
do spawntask_later {
511+
let mut stream = stream.take();
512+
let mut buf = [0];
513+
stream.read(buf);
514+
assert!(buf[0] == 99);
515+
rtdebug!("read");
516+
}
517+
}
518+
}
519+
520+
connect(0, addr);
521+
522+
fn connect(i: int, addr: IpAddr) {
523+
if i == MAX { return }
524+
525+
do spawntask_later {
526+
rtdebug!("connecting");
527+
let mut stream = TcpStream::connect(addr);
528+
// Connect again before writing
529+
connect(i + 1, addr);
530+
rtdebug!("writing");
531+
stream.write([99]);
532+
}
533+
}
534+
}
535+
}
343536

344537
}

src/libstd/rt/io/net/udp.rs

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ mod test {
115115
}
116116

117117
#[test]
118-
fn socket_smoke_test() {
118+
fn socket_smoke_test_ip4() {
119119
do run_in_newsched_task {
120120
let server_ip = next_test_ip4();
121121
let client_ip = next_test_ip4();
@@ -147,7 +147,39 @@ mod test {
147147
}
148148

149149
#[test]
150-
fn stream_smoke_test() {
150+
fn socket_smoke_test_ip6() {
151+
do run_in_newsched_task {
152+
let server_ip = next_test_ip6();
153+
let client_ip = next_test_ip6();
154+
155+
do spawntask_immediately {
156+
match UdpSocket::bind(server_ip) {
157+
Some(server) => {
158+
let mut buf = [0];
159+
match server.recvfrom(buf) {
160+
Some((nread, src)) => {
161+
assert_eq!(nread, 1);
162+
assert_eq!(buf[0], 99);
163+
assert_eq!(src, client_ip);
164+
}
165+
None => fail!()
166+
}
167+
}
168+
None => fail!()
169+
}
170+
}
171+
172+
do spawntask_immediately {
173+
match UdpSocket::bind(client_ip) {
174+
Some(client) => client.sendto([99], server_ip),
175+
None => fail!()
176+
}
177+
}
178+
}
179+
}
180+
181+
#[test]
182+
fn stream_smoke_test_ip4() {
151183
do run_in_newsched_task {
152184
let server_ip = next_test_ip4();
153185
let client_ip = next_test_ip4();
@@ -182,4 +214,41 @@ mod test {
182214
}
183215
}
184216
}
217+
218+
#[test]
219+
fn stream_smoke_test_ip6() {
220+
do run_in_newsched_task {
221+
let server_ip = next_test_ip6();
222+
let client_ip = next_test_ip6();
223+
224+
do spawntask_immediately {
225+
match UdpSocket::bind(server_ip) {
226+
Some(server) => {
227+
let server = ~server;
228+
let mut stream = server.connect(client_ip);
229+
let mut buf = [0];
230+
match stream.read(buf) {
231+
Some(nread) => {
232+
assert_eq!(nread, 1);
233+
assert_eq!(buf[0], 99);
234+
}
235+
None => fail!()
236+
}
237+
}
238+
None => fail!()
239+
}
240+
}
241+
242+
do spawntask_immediately {
243+
match UdpSocket::bind(client_ip) {
244+
Some(client) => {
245+
let client = ~client;
246+
let mut stream = client.connect(server_ip);
247+
stream.write([99]);
248+
}
249+
None => fail!()
250+
}
251+
}
252+
}
253+
}
185254
}

0 commit comments

Comments
 (0)