• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::windows::io::{FromRawSocket, RawSocket};
16 use std::os::windows::raw;
17 use std::{io, mem, net};
18 
19 use windows_sys::Win32::Networking::WinSock::{
20     bind as win_bind, closesocket, ioctlsocket, socket, ADDRESS_FAMILY, AF_INET, AF_INET6, FIONBIO,
21     INVALID_SOCKET, SOCKET, SOCKET_ERROR, SOCK_DGRAM,
22 };
23 
24 use crate::sys::windows::net::init;
25 use crate::sys::windows::socket_addr::socket_addr_trans;
26 
27 #[derive(Debug)]
28 pub(crate) struct UdpSock {
29     socket: SOCKET,
30 }
31 
32 impl UdpSock {
33     /// Gets new socket
new_socket(addr: SocketAddr) -> io::Result<UdpSock>34     pub(crate) fn new_socket(addr: SocketAddr) -> io::Result<UdpSock> {
35         if addr.is_ipv4() {
36             Self::create_socket(AF_INET, SOCK_DGRAM)
37         } else {
38             Self::create_socket(AF_INET6, SOCK_DGRAM)
39         }
40     }
41 
create_socket(domain: ADDRESS_FAMILY, socket_type: u16) -> io::Result<UdpSock>42     fn create_socket(domain: ADDRESS_FAMILY, socket_type: u16) -> io::Result<UdpSock> {
43         init();
44 
45         let socket = socket_syscall!(
46             socket(domain as i32, socket_type as i32, 0),
47             PartialEq::eq,
48             INVALID_SOCKET
49         )?;
50 
51         match socket_syscall!(ioctlsocket(socket, FIONBIO, &mut 1), PartialEq::ne, 0) {
52             Err(err) => {
53                 let _ = unsafe { closesocket(socket) };
54                 Err(err)
55             }
56             Ok(_) => Ok(UdpSock { socket }),
57         }
58     }
59 
60     /// System call gets net::UdpSocket
bind(self, addr: SocketAddr) -> io::Result<net::UdpSocket>61     pub(crate) fn bind(self, addr: SocketAddr) -> io::Result<net::UdpSocket> {
62         let socket = unsafe { net::UdpSocket::from_raw_socket(self.socket as raw::SOCKET) };
63 
64         let (raw_addr, addr_length) = socket_addr_trans(&addr);
65         socket_syscall!(
66             win_bind(self.socket, raw_addr.as_ptr(), addr_length),
67             PartialEq::eq,
68             SOCKET_ERROR
69         )?;
70         // must
71         mem::forget(self);
72         Ok(socket)
73     }
74 
75     /// Closes Socket
close(&self)76     pub(crate) fn close(&self) {
77         let _ = unsafe { net::UdpSocket::from_raw_socket(self.socket as RawSocket) };
78     }
79 }
80 
81 impl Drop for UdpSock {
drop(&mut self)82     fn drop(&mut self) {
83         self.close();
84     }
85 }
86