Skip to content

Commit 9edcb10

Browse files
olsonjefferybrson
authored andcommitted
std: addressing #2656 (ipv6 support in net::tcp)
.. there are some additional FIXME nags in net_tcp (L 1012) about blocking because libuv is holding unsafe ptrs to task local data. the proposed fix going is not really feasible w/ the current design, IMO, but i'll leave it there in case someone really wants to make the case without creating more hassle than it's worth.
1 parent e097ff6 commit 9edcb10

File tree

5 files changed

+88
-42
lines changed

5 files changed

+88
-42
lines changed

src/libstd/net_ip.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ mod v4 {
230230
fn try_parse_addr(ip: str) -> result::result<ip_addr,parse_addr_err> {
231231
unsafe {
232232
let INADDR_NONE = ll::get_INADDR_NONE();
233-
let ip_rep_result = parse_to_ipv4_rep(ip);
233+
let ip_rep_result = parse_to_ipv4_rep(ip);
234234
if result::is_err(ip_rep_result) {
235235
let err_str = result::get_err(ip_rep_result);
236236
ret result::err({err_msg: err_str})
@@ -243,7 +243,7 @@ mod v4 {
243243
let reformatted_name = uv_ip4_name(&new_addr);
244244
log(debug, #fmt("try_parse_addr: input ip: %s reparsed ip: %s",
245245
ip, reformatted_name));
246-
let ref_ip_rep_result = parse_to_ipv4_rep(reformatted_name);
246+
let ref_ip_rep_result = parse_to_ipv4_rep(reformatted_name);
247247
if result::is_err(ref_ip_rep_result) {
248248
let err_str = result::get_err(ref_ip_rep_result);
249249
ret result::err({err_msg: err_str})

src/libstd/net_tcp.rs

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -164,16 +164,35 @@ fn connect(-input_ip: ip::ip_addr, port: uint,
164164
alt input_ip {
165165
ipv4 {
166166
log(debug, "dealing w/ ipv4 connection..");
167-
let tcp_addr = ipv4_ip_addr_to_sockaddr_in(input_ip,
168-
port);
169-
let tcp_addr_ptr = ptr::addr_of(tcp_addr);
170167
let connect_req_ptr =
171168
ptr::addr_of((*socket_data_ptr).connect_req);
172-
alt uv::ll::tcp_connect(
173-
connect_req_ptr,
174-
stream_handle_ptr,
175-
tcp_addr_ptr,
176-
tcp_connect_on_connect_cb) {
169+
let addr_str = ip::format_addr(input_ip);
170+
let connect_result = alt input_ip {
171+
ip::ipv4(addr) {
172+
// have to "recreate" the sockaddr_in/6
173+
// since the ip_addr discards the port
174+
// info.. should probably add an additional
175+
// rust type that actually is closer to
176+
// what the libuv API expects (ip str + port num)
177+
log(debug, #fmt("addr: %?", addr));
178+
let in_addr = uv::ll::ip4_addr(addr_str, port as int);
179+
uv::ll::tcp_connect(
180+
connect_req_ptr,
181+
stream_handle_ptr,
182+
ptr::addr_of(in_addr),
183+
tcp_connect_on_connect_cb)
184+
}
185+
ip::ipv6(addr) {
186+
log(debug, #fmt("addr: %?", addr));
187+
let in_addr = uv::ll::ip6_addr(addr_str, port as int);
188+
uv::ll::tcp_connect6(
189+
connect_req_ptr,
190+
stream_handle_ptr,
191+
ptr::addr_of(in_addr),
192+
tcp_connect_on_connect_cb)
193+
}
194+
};
195+
alt connect_result {
177196
0i32 {
178197
log(debug, "tcp_connect successful");
179198
// reusable data that we'll have for the
@@ -598,15 +617,27 @@ fn listen_common(-host_ip: ip::ip_addr, port: uint, backlog: uint,
598617
// nested within a comm::listen block)
599618
let loc_ip = copy(host_ip);
600619
iotask::interact(iotask) {|loop_ptr|
601-
let tcp_addr = ipv4_ip_addr_to_sockaddr_in(loc_ip,
602-
port);
603620
alt uv::ll::tcp_init(loop_ptr, server_stream_ptr) {
604621
0i32 {
605622
uv::ll::set_data_for_uv_handle(
606623
server_stream_ptr,
607624
server_data_ptr);
608-
alt uv::ll::tcp_bind(server_stream_ptr,
609-
ptr::addr_of(tcp_addr)) {
625+
let addr_str = ip::format_addr(loc_ip);
626+
let bind_result = alt loc_ip {
627+
ip::ipv4(addr) {
628+
log(debug, #fmt("addr: %?", addr));
629+
let in_addr = uv::ll::ip4_addr(addr_str, port as int);
630+
uv::ll::tcp_bind(server_stream_ptr,
631+
ptr::addr_of(in_addr))
632+
}
633+
ip::ipv6(addr) {
634+
log(debug, #fmt("addr: %?", addr));
635+
let in_addr = uv::ll::ip6_addr(addr_str, port as int);
636+
uv::ll::tcp_bind6(server_stream_ptr,
637+
ptr::addr_of(in_addr))
638+
}
639+
};
640+
alt bind_result {
610641
0i32 {
611642
alt uv::ll::listen(server_stream_ptr,
612643
backlog as libc::c_int,
@@ -1205,19 +1236,6 @@ type tcp_buffered_socket_data = {
12051236
mut buf: [u8]
12061237
};
12071238

1208-
// convert rust ip_addr to libuv's native representation
1209-
fn ipv4_ip_addr_to_sockaddr_in(input_ip: ip::ip_addr,
1210-
port: uint) -> uv::ll::sockaddr_in unsafe {
1211-
// FIXME (#2656): ipv6
1212-
let addr_str = ip::format_addr(input_ip);
1213-
alt input_ip {
1214-
ip::ipv4(addr) {
1215-
uv::ll::ip4_addr(addr_str, port as int)
1216-
}
1217-
_ { fail "only works w/ ipv4";}
1218-
}
1219-
}
1220-
12211239
//#[cfg(test)]
12221240
mod test {
12231241
// FIXME don't run on fbsd or linux 32 bit (#2064)

src/libstd/uv_ll.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,14 @@ native mod rustrt {
542542
// FIXME ref #2064
543543
fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t,
544544
++addr: *sockaddr_in) -> libc::c_int;
545+
// FIXME ref #2064
546+
fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t,
547+
tcp_handle_ptr: *uv_tcp_t,
548+
++after_cb: *u8,
549+
++addr: *sockaddr_in6) -> libc::c_int;
550+
// FIXME ref #2064
551+
fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t,
552+
++addr: *sockaddr_in6) -> libc::c_int;
545553
fn rust_uv_listen(stream: *libc::c_void, backlog: libc::c_int,
546554
cb: *u8) -> libc::c_int;
547555
fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void)
@@ -651,11 +659,26 @@ unsafe fn tcp_connect(connect_ptr: *uv_connect_t,
651659
after_connect_cb, addr_ptr);
652660
}
653661
// FIXME ref #2064
662+
unsafe fn tcp_connect6(connect_ptr: *uv_connect_t,
663+
tcp_handle_ptr: *uv_tcp_t,
664+
addr_ptr: *sockaddr_in6,
665+
++after_connect_cb: *u8)
666+
-> libc::c_int {
667+
ret rustrt::rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr,
668+
after_connect_cb, addr_ptr);
669+
}
670+
// FIXME ref #2064
654671
unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t,
655672
addr_ptr: *sockaddr_in) -> libc::c_int {
656673
ret rustrt::rust_uv_tcp_bind(tcp_server_ptr,
657674
addr_ptr);
658675
}
676+
// FIXME ref #2064
677+
unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t,
678+
addr_ptr: *sockaddr_in6) -> libc::c_int {
679+
ret rustrt::rust_uv_tcp_bind6(tcp_server_ptr,
680+
addr_ptr);
681+
}
659682

660683
unsafe fn listen<T>(stream: *T, backlog: libc::c_int,
661684
cb: *u8) -> libc::c_int {

src/rt/rust_uv.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -238,32 +238,36 @@ rust_uv_tcp_connect(uv_connect_t* connect_ptr,
238238
uv_tcp_t* tcp_ptr,
239239
uv_connect_cb cb,
240240
sockaddr_in* addr_ptr) {
241-
rust_task* task = rust_get_current_task();
242-
LOG(task, stdlib, "inside rust_uv_tcp_connect");
243241
// FIXME ref #2064
244242
sockaddr_in addr = *addr_ptr;
245-
LOG(task, stdlib, "before tcp_connect .. port: %d",
246-
addr.sin_port);
247-
LOG(task, stdlib, "before tcp_connect.. tcp stream:" \
248-
"%lu cb ptr: %lu",
249-
(unsigned long int)tcp_ptr, (unsigned long int)cb);
250243
int result = uv_tcp_connect(connect_ptr, tcp_ptr, addr, cb);
251-
LOG(task, stdlib, "leaving rust_uv_tcp_connect.." \
252-
"and result: %d",
253-
result);
254244
return result;
255245
}
256246

257247
extern "C" int
258248
rust_uv_tcp_bind(uv_tcp_t* tcp_server, sockaddr_in* addr_ptr) {
259249
// FIXME ref #2064
260-
rust_task* task = rust_get_current_task();
261250
sockaddr_in addr = *addr_ptr;
262-
LOG(task, stdlib, "before uv_tcp_bind .. tcp_server:" \
263-
"%lu port: %d",
264-
(unsigned long int)tcp_server, addr.sin_port);
265251
return uv_tcp_bind(tcp_server, addr);
266252
}
253+
extern "C" int
254+
rust_uv_tcp_connect6(uv_connect_t* connect_ptr,
255+
uv_tcp_t* tcp_ptr,
256+
uv_connect_cb cb,
257+
sockaddr_in6* addr_ptr) {
258+
// FIXME ref #2064
259+
sockaddr_in6 addr = *addr_ptr;
260+
int result = uv_tcp_connect6(connect_ptr, tcp_ptr, addr, cb);
261+
return result;
262+
}
263+
264+
extern "C" int
265+
rust_uv_tcp_bind6
266+
(uv_tcp_t* tcp_server, sockaddr_in6* addr_ptr) {
267+
// FIXME ref #2064
268+
sockaddr_in6 addr = *addr_ptr;
269+
return uv_tcp_bind6(tcp_server, addr);
270+
}
267271

268272
extern "C" int
269273
rust_uv_listen(uv_stream_t* stream, int backlog,
@@ -328,7 +332,6 @@ extern "C" unsigned int
328332
rust_uv_helper_get_INADDR_NONE() {
329333
return INADDR_NONE;
330334
}
331-
332335
extern "C" uv_stream_t*
333336
rust_uv_get_stream_handle_from_connect_req(uv_connect_t* connect) {
334337
return connect->handle;

src/rt/rustrt.def.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ rust_uv_ip6_addr
116116
rust_uv_ip6_name
117117
rust_uv_tcp_connect
118118
rust_uv_tcp_bind
119+
rust_uv_tcp_connect6
120+
rust_uv_tcp_bind6
119121
rust_uv_listen
120122
rust_uv_accept
121123
rust_uv_write

0 commit comments

Comments
 (0)