Expand description

This crate provides a type that can act as a platform-native socket address (i.e. libc::sockaddr)

Motivation

The std crate provides SocketAddr for managing socket addresses. Its V4 variant encapsulates libc::sockaddr_in and its V6 variant encapsulates libc::sockaddr_in6. However there is no easy way to convert SocketAddr from/into a libc::sockaddr because SocketAddr is a rust enum.

This crate provides OsSocketAddr which holds a libc::sockaddr (containing an IPv4 or IPv6 address) and the conversion functions from/into SocketAddr.

Example

extern crate libc;
extern crate os_socketaddr;

use std::net::SocketAddr;
use self::libc::{c_int, c_void, size_t, ssize_t};
use self::os_socketaddr::OsSocketAddr;

#[cfg(target_family = "unix")]
fn sendto(socket: c_int, buf: &[u8], dst: SocketAddr) -> ssize_t
{
    let addr : OsSocketAddr = dst.into();
    unsafe {
        libc::sendto(socket, buf.as_ptr() as *const c_void, buf.len() as size_t, 0,
                     addr.as_ptr(), addr.len())
    }
}

#[cfg(target_family = "unix")]
fn recvfrom(socket: c_int, buf: &mut[u8]) -> (ssize_t, Option<SocketAddr>)
{
    let mut addr = OsSocketAddr::new();
    let mut addrlen = addr.capacity();
    let nb = unsafe {
        libc::recvfrom(socket, buf.as_mut_ptr() as *mut c_void, buf.len(), 0,
                       addr.as_mut_ptr(), &mut addrlen as *mut _)
    };
    (nb, addr.into())
}

#[cfg(target_family = "windows")]
fn sendto(socket: winapi::um::winsock2::SOCKET, buf: &mut [u8], dst: SocketAddr) -> ssize_t
{
    let addr : OsSocketAddr = dst.into();
    let mut wsabuf = winapi::shared::ws2def::WSABUF {
        len: buf.len() as u32,
        buf: buf.as_ptr() as *mut i8,
    };
    let mut numberOfBytesSent: u32 = 0;
    let nb = unsafe {
        winapi::um::winsock2::WSASendTo(socket, &mut wsabuf, 1u32, &mut numberOfBytesSent, 0u32,
                                        addr.as_ptr(), addr.len() as i32,
                                        std::ptr::null_mut::<winapi::um::minwinbase::OVERLAPPED>(), None)
    };
    if nb == 0 {
        numberOfBytesSent as isize
    } else {
        -1
    }
}

#[cfg(target_family = "windows")]
fn recvfrom(socket: winapi::um::winsock2::SOCKET, buf: &mut[u8]) -> (ssize_t, Option<SocketAddr>)
{
    let mut addr = OsSocketAddr::new();
    let mut addrlen = addr.capacity();
    let mut wsabuf = winapi::shared::ws2def::WSABUF {
        len: buf.len() as u32,
        buf: buf.as_ptr() as *mut i8,
    };
    let mut numberOfBytesRecvd: u32 = 0;
    let mut flags: u32 = 0;
    let nb = unsafe {
        winapi::um::winsock2::WSARecvFrom(socket, &mut wsabuf, 1u32, &mut numberOfBytesRecvd, &mut flags,
                                          addr.as_mut_ptr(), &mut addrlen as *mut _,
                                          std::ptr::null_mut::<winapi::um::minwinbase::OVERLAPPED>(), None)
    };
    if nb == 0 {
        (numberOfBytesRecvd as isize, addr.into())
    } else {
        (-1, None)
    }
}

Structs

A type for handling platform-native socket addresses (struct sockaddr)