Skip to content

Commit 8e05ced

Browse files
committed
Refactor Socket::local_addr
1 parent f9e738f commit 8e05ced

File tree

3 files changed

+35
-33
lines changed

3 files changed

+35
-33
lines changed

src/socket.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,16 @@ impl Socket {
198198
sys::accept(self.inner).map(|(inner, addr)| (Socket { inner }, addr))
199199
}
200200

201-
/// Returns the socket address of the local half of this TCP connection.
201+
/// Returns the socket address of the local half of this socket.
202+
///
203+
/// # Notes
204+
///
205+
/// Depending on the OS this may return an error if the socket is not
206+
/// [bound].
207+
///
208+
/// [bound]: Socket::bind
202209
pub fn local_addr(&self) -> io::Result<SockAddr> {
203-
self.inner().local_addr()
210+
sys::getsockname(self.inner)
204211
}
205212

206213
/// Returns the socket address of the remote peer of this TCP connection.

src/sys/unix.rs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#[cfg(not(target_os = "redox"))]
1010
use std::io::{IoSlice, IoSliceMut};
1111
use std::io::{Read, Write};
12+
use std::mem::{self, size_of_val};
1213
use std::net::Shutdown;
1314
use std::net::{self, Ipv4Addr, Ipv6Addr};
1415
#[cfg(feature = "all")]
@@ -21,7 +22,7 @@ use std::path::Path;
2122
use std::ptr;
2223
use std::sync::atomic::{AtomicBool, Ordering};
2324
use std::time::Duration;
24-
use std::{cmp, fmt, io, mem};
25+
use std::{cmp, fmt, io};
2526

2627
use libc::{self, c_void, in6_addr, in_addr, ssize_t};
2728

@@ -324,13 +325,20 @@ pub(crate) fn listen(fd: SysSocket, backlog: i32) -> io::Result<()> {
324325
pub(crate) fn accept(fd: SysSocket) -> io::Result<(SysSocket, SockAddr)> {
325326
// Safety: zeroed `sockaddr_storage` is valid.
326327
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
327-
let mut len = mem::size_of_val(&storage) as socklen_t;
328+
let mut len = size_of_val(&storage) as socklen_t;
328329
syscall!(accept(fd, &mut storage as *mut _ as *mut _, &mut len)).map(|fd| {
329330
let addr = unsafe { SockAddr::from_raw_parts(&storage as *const _ as *const _, len) };
330331
(fd, addr)
331332
})
332333
}
333334

335+
pub(crate) fn getsockname(fd: SysSocket) -> io::Result<SockAddr> {
336+
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
337+
let mut len = size_of_val(&storage) as libc::socklen_t;
338+
syscall!(getsockname(fd, &mut storage as *mut _ as *mut _, &mut len,))
339+
.map(|_| unsafe { SockAddr::from_raw_parts(&storage as *const _ as *const _, len) })
340+
}
341+
334342
/// Unix only API.
335343
impl crate::Socket {
336344
/// Accept a new incoming connection from this listener.
@@ -426,17 +434,6 @@ pub struct Socket {
426434
}
427435

428436
impl Socket {
429-
pub fn local_addr(&self) -> io::Result<SockAddr> {
430-
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
431-
let mut len = mem::size_of_val(&storage) as libc::socklen_t;
432-
syscall!(getsockname(
433-
self.fd,
434-
&mut storage as *mut _ as *mut _,
435-
&mut len,
436-
))?;
437-
Ok(unsafe { SockAddr::from_raw_parts(&storage as *const _ as *const _, len) })
438-
}
439-
440437
pub fn peer_addr(&self) -> io::Result<SockAddr> {
441438
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
442439
let mut len = mem::size_of_val(&storage) as libc::socklen_t;
@@ -1052,7 +1049,7 @@ impl fmt::Debug for Socket {
10521049
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10531050
let mut f = f.debug_struct("Socket");
10541051
f.field("fd", &self.fd);
1055-
if let Ok(addr) = self.local_addr() {
1052+
if let Ok(addr) = getsockname(self.fd) {
10561053
f.field("local_addr", &addr);
10571054
}
10581055
if let Ok(addr) = self.peer_addr() {

src/sys/windows.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::cmp;
1010
use std::fmt;
1111
use std::io;
1212
use std::io::{IoSlice, IoSliceMut, Read, Write};
13-
use std::mem;
13+
use std::mem::{self, size_of_val};
1414
use std::net::Shutdown;
1515
use std::net::{self, Ipv4Addr, Ipv6Addr};
1616
use std::os::windows::prelude::*;
@@ -169,7 +169,7 @@ pub(crate) fn listen(socket: SysSocket, backlog: i32) -> io::Result<()> {
169169
pub(crate) fn accept(socket: SysSocket) -> io::Result<(SysSocket, SockAddr)> {
170170
// Safety: zeroed `SOCKADDR_STORAGE` is valid.
171171
let mut storage: SOCKADDR_STORAGE = unsafe { mem::zeroed() };
172-
let mut len = mem::size_of_val(&storage) as c_int;
172+
let mut len = size_of_val(&storage) as c_int;
173173
syscall!(
174174
accept(socket, &mut storage as *mut _ as *mut _, &mut len),
175175
PartialEq::eq,
@@ -181,6 +181,18 @@ pub(crate) fn accept(socket: SysSocket) -> io::Result<(SysSocket, SockAddr)> {
181181
})
182182
}
183183

184+
pub(crate) fn getsockname(socket: SysSocket) -> io::Result<SockAddr> {
185+
// Safety: zeroed `SOCKADDR_STORAGE` is valid.
186+
let mut storage: SOCKADDR_STORAGE = unsafe { mem::zeroed() };
187+
let mut len = size_of_val(&storage) as c_int;
188+
syscall!(
189+
getsockname(socket, &mut storage as *mut _ as *mut _, &mut len),
190+
PartialEq::eq,
191+
sock::SOCKET_ERROR
192+
)
193+
.map(|_| unsafe { SockAddr::from_raw_parts(&storage as *const _ as *const _, len) })
194+
}
195+
184196
impl crate::Socket {
185197
/// Sets `HANDLE_FLAG_INHERIT` to zero using `SetHandleInformation`.
186198
pub fn set_no_inherit(&self) -> io::Result<()> {
@@ -199,20 +211,6 @@ pub struct Socket {
199211
}
200212

201213
impl Socket {
202-
pub fn local_addr(&self) -> io::Result<SockAddr> {
203-
unsafe {
204-
let mut storage: SOCKADDR_STORAGE = mem::zeroed();
205-
let mut len = mem::size_of_val(&storage) as c_int;
206-
if sock::getsockname(self.socket, &mut storage as *mut _ as *mut _, &mut len) != 0 {
207-
return Err(last_error());
208-
}
209-
Ok(SockAddr::from_raw_parts(
210-
&storage as *const _ as *const _,
211-
len,
212-
))
213-
}
214-
}
215-
216214
pub fn peer_addr(&self) -> io::Result<SockAddr> {
217215
unsafe {
218216
let mut storage: SOCKADDR_STORAGE = mem::zeroed();
@@ -894,7 +892,7 @@ impl fmt::Debug for Socket {
894892
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
895893
let mut f = f.debug_struct("Socket");
896894
f.field("socket", &self.socket);
897-
if let Ok(addr) = self.local_addr() {
895+
if let Ok(addr) = getsockname(self.socket) {
898896
f.field("local_addr", &addr);
899897
}
900898
if let Ok(addr) = self.peer_addr() {

0 commit comments

Comments
 (0)