1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 use std::net::SocketAddr; 15 use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; 16 use std::{io, net}; 17 18 use libc::{c_int, AF_INET, AF_INET6, SOCK_DGRAM}; 19 20 use super::super::socket_addr::socket_addr_trans; 21 use crate::sys::socket::socket_new; 22 use crate::UdpSocket; 23 24 pub(crate) struct UdpSock { 25 socket: c_int, 26 } 27 28 impl UdpSock { new_socket(addr: SocketAddr) -> io::Result<UdpSock>29 pub(crate) fn new_socket(addr: SocketAddr) -> io::Result<UdpSock> { 30 if addr.is_ipv4() { 31 UdpSock::create_socket(AF_INET, SOCK_DGRAM) 32 } else { 33 UdpSock::create_socket(AF_INET6, SOCK_DGRAM) 34 } 35 } 36 create_socket(domain: c_int, socket_type: c_int) -> io::Result<UdpSock>37 pub(crate) fn create_socket(domain: c_int, socket_type: c_int) -> io::Result<UdpSock> { 38 let socket = socket_new(domain, socket_type)?; 39 Ok(UdpSock { 40 socket: socket as c_int, 41 }) 42 } 43 bind(self, addr: SocketAddr) -> io::Result<UdpSocket>44 pub(crate) fn bind(self, addr: SocketAddr) -> io::Result<UdpSocket> { 45 let udp_socket = UdpSocket { 46 inner: unsafe { net::UdpSocket::from_raw_fd(self.socket) }, 47 }; 48 let (raw_addr, addr_length) = socket_addr_trans(&addr); 49 match syscall!(bind(self.socket, raw_addr.as_ptr(), addr_length)) { 50 Err(err) if err.raw_os_error() != Some(libc::EINPROGRESS) => Err(err), 51 _ => Ok(udp_socket), 52 } 53 } 54 } 55 56 impl AsRawFd for UdpSock { as_raw_fd(&self) -> RawFd57 fn as_raw_fd(&self) -> RawFd { 58 self.socket 59 } 60 } 61 62 impl FromRawFd for UdpSock { from_raw_fd(fd: RawFd) -> UdpSock63 unsafe fn from_raw_fd(fd: RawFd) -> UdpSock { 64 UdpSock { socket: fd } 65 } 66 } 67