mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Bug 1716518 - Upgrade the net2 crate to v0.2.37. r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D117746
This commit is contained in:
parent
7bf37eeab8
commit
77cb78ae29
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -3414,9 +3414,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "net2"
|
||||
version = "0.2.33"
|
||||
version = "0.2.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
||||
checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"libc",
|
||||
|
2
third_party/rust/net2/.cargo-checksum.json
vendored
2
third_party/rust/net2/.cargo-checksum.json
vendored
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"c18ec02a8566f054a27e18df2ac53856a74864fad952a41abda096c91caae106","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"c13834771aa1973a02dfbf99c282850ea1d6974269ebe9081cd2853a5ac59c93","appveyor.yml":"6e3173d907ccfa65e289c99042cb29d4a23b9d1f4ec5bf7afa6c0d65365bab54","src/ext.rs":"b9300ae246e9ac451889f146ece8bb6ed4a95482edf806373de5af759cd09360","src/lib.rs":"8d8a171090b75e86e7505921460fba072db0077942edd11c4a3c8a70e9164eef","src/socket.rs":"a033d04061d95c4fea3eb78ce25f147d3b669034681e4119d00bc78b817a8096","src/sys/redox/impls.rs":"90059116f0514bd44dbf282a3e8d7b192c99e1a78a34ebacb00f2d325ca0f8b0","src/sys/redox/mod.rs":"137013d409fd174fed0ceb3eceb2c17d15f34a3af70c7d237c06dd3a144affc1","src/sys/unix/impls.rs":"05f123226e8fe7559317d50864021650b2455d25d01a9aff1c65c01ae26cf4ef","src/sys/unix/mod.rs":"bb28a7275eac021132b01206d134802902d616c0be3e82100b45a3ff1eba4c02","src/sys/windows/impls.rs":"bee70b7cd45055c4eaa1967f7aad7ec46639de458c71ed6f3e97a2f7b2c49281","src/sys/windows/mod.rs":"0706f1587af0f693f75e8597e4196075a3f673c89727dd865447da306974bf35","src/tcp.rs":"0bebf5cca75714151de30c8f2d7697ca519c57da065e93ba81796bce04673f8d","src/udp.rs":"8af5a55a4ae5e4120ffe18dcc4dc24072e18da34bf3591a02b18653e5d3e8ac8","src/unix.rs":"fe9cdbd75ef2e1fafc128d1abb5f32500eaf0b674aa618d837e06ab1d0dc6687","src/utils.rs":"d31de5333a6fa2f5c99b64cc937be596888d9863264632e6bc6b36b30197fa5b","tests/all.rs":"12cb4616c842f655ece1b477664d41821f95b3051053da641b1d85026ee18274"},"package":"42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"}
|
||||
{"files":{"Cargo.toml":"3ef21068c8bd6d2afddf710600ae305511544f5e1ce86a8f715834ab9c3ff8b9","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"a99cb0401bd49e68c945f6a249175dd5c4a5117b2c8cc5d5fb7dea369002574e","src/ext.rs":"fd072307ebbaa01cfe1fd7553d7f42d27093b2bd32dd81d419d2e1c9423495a0","src/lib.rs":"a5e429c904fa13291dee5ed5df6c20adcebbaa56fc0312d475fd2056e9974153","src/socket.rs":"1468f54b4ce8ec2f94d8a23fba4c59752cbd2f447f29e7f0ae032785fdd916f4","src/sys/redox/impls.rs":"90059116f0514bd44dbf282a3e8d7b192c99e1a78a34ebacb00f2d325ca0f8b0","src/sys/redox/mod.rs":"137013d409fd174fed0ceb3eceb2c17d15f34a3af70c7d237c06dd3a144affc1","src/sys/unix/impls.rs":"05f123226e8fe7559317d50864021650b2455d25d01a9aff1c65c01ae26cf4ef","src/sys/unix/mod.rs":"e06b26bad48c815b9a2af4509d1873333e2aad0031980f6d2625f72542698d56","src/sys/wasi/impls.rs":"da4e95a27a765b64fbbebce55b860020ac891456085ed706d5f8f391e0d1cddf","src/sys/wasi/mod.rs":"e88b02f4d5e0ae558f093d49cc0bb1b3cdf86ede625d00ed9231f0ab414e483f","src/sys/windows/impls.rs":"bee70b7cd45055c4eaa1967f7aad7ec46639de458c71ed6f3e97a2f7b2c49281","src/sys/windows/mod.rs":"31a73007ea65a4905e93395f86105d2ef9fb84d3d795511c6cfdc8cba595cb0c","src/tcp.rs":"0bebf5cca75714151de30c8f2d7697ca519c57da065e93ba81796bce04673f8d","src/udp.rs":"8af5a55a4ae5e4120ffe18dcc4dc24072e18da34bf3591a02b18653e5d3e8ac8","src/unix.rs":"1156707694cb1f002a2eb2144bf205a73412e1661fd196a8a2a7bc8ea5aaad2d","src/utils.rs":"d31de5333a6fa2f5c99b64cc937be596888d9863264632e6bc6b36b30197fa5b"},"package":"391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae"}
|
15
third_party/rust/net2/Cargo.toml
vendored
15
third_party/rust/net2/Cargo.toml
vendored
@ -3,7 +3,7 @@
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g. crates.io) dependencies
|
||||
# to registry (e.g., crates.io) dependencies
|
||||
#
|
||||
# If you believe there's an error in this file please file an
|
||||
# issue against the rust-lang/cargo repository. If you're
|
||||
@ -12,14 +12,15 @@
|
||||
|
||||
[package]
|
||||
name = "net2"
|
||||
version = "0.2.33"
|
||||
version = "0.2.37"
|
||||
authors = ["Alex Crichton <alex@alexcrichton.com>"]
|
||||
include = ["Cargo.toml", "LICENSE-APACHE", "LICENSE-MIT", "README.md", "src/**/*.rs"]
|
||||
description = "Extensions to the standard library's networking types as proposed in RFC 1158.\n"
|
||||
homepage = "https://github.com/rust-lang-nursery/net2-rs"
|
||||
documentation = "https://doc.rust-lang.org/net2-rs/"
|
||||
homepage = "https://github.com/deprecrated/net2-rs"
|
||||
documentation = "https://docs.rs/net2/~0.2"
|
||||
readme = "README.md"
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/rust-lang-nursery/net2-rs"
|
||||
repository = "https://github.com/deprecrated/net2-rs"
|
||||
[dependencies.cfg-if]
|
||||
version = "0.1"
|
||||
|
||||
@ -27,8 +28,8 @@ version = "0.1"
|
||||
default = ["duration"]
|
||||
duration = []
|
||||
nightly = []
|
||||
[target."cfg(any(target_os=\"redox\", unix))".dependencies.libc]
|
||||
version = "0.2.42"
|
||||
[target."cfg(any(target_os=\"redox\", unix, target_os=\"wasi\"))".dependencies.libc]
|
||||
version = "0.2.54"
|
||||
[target."cfg(windows)".dependencies.winapi]
|
||||
version = "0.3"
|
||||
features = ["handleapi", "winsock2", "ws2def", "ws2ipdef", "ws2tcpip"]
|
||||
|
22
third_party/rust/net2/README.md
vendored
22
third_party/rust/net2/README.md
vendored
@ -1,21 +1,17 @@
|
||||
# net2
|
||||
|
||||
[![Build Status](https://travis-ci.org/rust-lang-nursery/net2-rs.svg?branch=master)](https://travis-ci.org/rust-lang-nursery/net2-rs)
|
||||
[![Build status](https://ci.appveyor.com/api/projects/status/ns78f02jt2uvd2lp?svg=true)](https://ci.appveyor.com/project/alexcrichton/net2-rs)
|
||||
|
||||
[Documentation](https://docs.rs/net2/0.2.32/net2/)
|
||||
|
||||
Extensions to the standard library's networking types, proposed in [RFC
|
||||
1158][rfc].
|
||||
|
||||
Extensions to the standard library's networking types, proposed in [RFC 1158][rfc].
|
||||
|
||||
[rfc]: https://github.com/alexcrichton/rfcs/blob/net2.1/text/0000-io-net-2.1.md
|
||||
|
||||
```toml
|
||||
# Cargo.toml
|
||||
[dependencies]
|
||||
net2 = "0.2"
|
||||
```
|
||||
[![Build Status](https://github.com/deprecrated/net2-rs/workflows/CI/badge.svg)](https://github.com/deprecrated/net2-rs/actions?query=workflow%3ACI+branch%3Amaster)
|
||||
[![Documentation](https://docs.rs/net2/badge.svg?version=0.2)](https://docs.rs/net2/~0.2)
|
||||
|
||||
# net2 is Deprecated
|
||||
|
||||
Prospective and existing consumers are encouraged to consider
|
||||
[socket2](https://crates.io/crates/socket2) instead.
|
||||
|
||||
|
||||
# License
|
||||
|
||||
|
17
third_party/rust/net2/appveyor.yml
vendored
17
third_party/rust/net2/appveyor.yml
vendored
@ -1,17 +0,0 @@
|
||||
environment:
|
||||
matrix:
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
- TARGET: i686-pc-windows-msvc
|
||||
- TARGET: i686-pc-windows-gnu
|
||||
install:
|
||||
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe"
|
||||
- rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
|
||||
- SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin
|
||||
- SET PATH=%PATH%;C:\MinGW\bin
|
||||
- rustc -V
|
||||
- cargo -V
|
||||
|
||||
build: false
|
||||
|
||||
test_script:
|
||||
- cargo test --verbose --features nightly --target %TARGET%
|
92
third_party/rust/net2/src/ext.rs
vendored
92
third_party/rust/net2/src/ext.rs
vendored
@ -23,11 +23,13 @@ use socket;
|
||||
cfg_if! {
|
||||
if #[cfg(any(target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "haiku",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_env = "uclibc"))] {
|
||||
use libc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP;
|
||||
use libc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP;
|
||||
@ -38,13 +40,15 @@ cfg_if! {
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
#[cfg(any(unix, target_os = "redox"))] use libc::*;
|
||||
#[cfg(any(unix, target_os = "redox", target_os = "wasi"))] use libc::*;
|
||||
#[cfg(any(unix, target_os = "redox"))] use std::os::unix::prelude::*;
|
||||
#[cfg(target_os = "wasi")] use std::os::wasi::prelude::*;
|
||||
#[cfg(target_os = "redox")] pub type Socket = usize;
|
||||
#[cfg(unix)] pub type Socket = c_int;
|
||||
#[cfg(target_os = "wasi")] pub type Socket = std::os::wasi::io::RawFd;
|
||||
#[cfg(windows)] pub type Socket = SOCKET;
|
||||
#[cfg(windows)] use std::os::windows::prelude::*;
|
||||
#[cfg(windows)] use sys::c::*;
|
||||
#[cfg(any(windows, target_os = "wasi"))] use sys::c::*;
|
||||
|
||||
#[cfg(windows)] const SIO_KEEPALIVE_VALS: DWORD = 0x98000004;
|
||||
#[cfg(windows)]
|
||||
@ -55,10 +59,16 @@ struct tcp_keepalive {
|
||||
keepaliveinterval: c_ulong,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "redox")] fn v(opt: c_int) -> c_int { opt }
|
||||
#[cfg(unix)] fn v(opt: c_int) -> c_int { opt }
|
||||
#[cfg(any(unix, target_os = "redox", target_os = "wasi"))] fn v(opt: c_int) -> c_int { opt }
|
||||
#[cfg(windows)] fn v(opt: IPPROTO) -> c_int { opt as c_int }
|
||||
|
||||
#[cfg(target_os = "wasi")]
|
||||
pub fn set_opt<T: Copy>(_sock: Socket, _opt: c_int, _val: c_int,
|
||||
_payload: T) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "wasi"))]
|
||||
pub fn set_opt<T: Copy>(sock: Socket, opt: c_int, val: c_int,
|
||||
payload: T) -> io::Result<()> {
|
||||
unsafe {
|
||||
@ -67,10 +77,15 @@ pub fn set_opt<T: Copy>(sock: Socket, opt: c_int, val: c_int,
|
||||
let sock = sock as c_int;
|
||||
try!(::cvt(setsockopt(sock, opt, val, payload as *const _,
|
||||
mem::size_of::<T>() as socklen_t)));
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "wasi")]
|
||||
pub fn get_opt<T: Copy>(_sock: Socket, _opt: c_int, _val: c_int) -> io::Result<T> {
|
||||
unimplemented!()
|
||||
}
|
||||
#[cfg(not(target_os = "wasi"))]
|
||||
pub fn get_opt<T: Copy>(sock: Socket, opt: c_int, val: c_int) -> io::Result<T> {
|
||||
unsafe {
|
||||
let mut slot: T = mem::zeroed();
|
||||
@ -641,11 +656,7 @@ pub trait AsSock {
|
||||
fn as_sock(&self) -> Socket;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
impl<T: AsRawFd> AsSock for T {
|
||||
fn as_sock(&self) -> Socket { self.as_raw_fd() }
|
||||
}
|
||||
#[cfg(unix)]
|
||||
#[cfg(any(unix, target_os = "redox", target_os = "wasi"))]
|
||||
impl<T: AsRawFd> AsSock for T {
|
||||
fn as_sock(&self) -> Socket { self.as_raw_fd() }
|
||||
}
|
||||
@ -657,7 +668,7 @@ impl<T: AsRawSocket> AsSock for T {
|
||||
cfg_if! {
|
||||
if #[cfg(any(target_os = "macos", target_os = "ios"))] {
|
||||
use libc::TCP_KEEPALIVE as KEEPALIVE_OPTION;
|
||||
} else if #[cfg(any(target_os = "openbsd", target_os = "netbsd"))] {
|
||||
} else if #[cfg(any(target_os = "haiku", target_os = "netbsd", target_os = "openbsd"))] {
|
||||
use libc::SO_KEEPALIVE as KEEPALIVE_OPTION;
|
||||
} else if #[cfg(unix)] {
|
||||
use libc::TCP_KEEPIDLE as KEEPALIVE_OPTION;
|
||||
@ -750,6 +761,16 @@ impl TcpStreamExt for TcpStream {
|
||||
Ok(Some((secs as u32) * 1000))
|
||||
}
|
||||
|
||||
#[cfg(target_os = "wasi")]
|
||||
fn set_keepalive_ms(&self, _keepalive: Option<u32>) -> io::Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[cfg(target_os = "wasi")]
|
||||
fn keepalive_ms(&self) -> io::Result<Option<u32>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn set_keepalive_ms(&self, keepalive: Option<u32>) -> io::Result<()> {
|
||||
let ms = keepalive.unwrap_or(INFINITE);
|
||||
@ -872,7 +893,7 @@ impl TcpStreamExt for TcpStream {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "redox", unix))]
|
||||
#[cfg(any(target_os = "redox", unix, target_os = "wasi"))]
|
||||
fn ms2timeout(dur: Option<u32>) -> timeval {
|
||||
// TODO: be more rigorous
|
||||
match dur {
|
||||
@ -884,7 +905,7 @@ fn ms2timeout(dur: Option<u32>) -> timeval {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "redox", unix))]
|
||||
#[cfg(any(target_os = "redox", unix, target_os = "wasi"))]
|
||||
fn timeout2ms(dur: timeval) -> Option<u32> {
|
||||
if dur.tv_sec == 0 && dur.tv_usec == 0 {
|
||||
None
|
||||
@ -929,7 +950,7 @@ fn dur2linger(dur: Option<Duration>) -> linger {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "redox", unix))]
|
||||
#[cfg(any(target_os = "redox", unix, target_os = "wasi"))]
|
||||
fn dur2linger(dur: Option<Duration>) -> linger {
|
||||
match dur {
|
||||
Some(d) => {
|
||||
@ -1193,6 +1214,22 @@ impl UdpSocketExt for UdpSocket {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "wasi")]
|
||||
fn send(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
let _so_datalen: *mut sys::c::size_t = &mut 0;
|
||||
unsafe {
|
||||
let _errno = libc::__wasi_sock_send(
|
||||
self.as_sock() as libc::__wasi_fd_t,
|
||||
buf.as_ptr() as *const _,
|
||||
buf.len(),
|
||||
0,
|
||||
_so_datalen,
|
||||
);
|
||||
// TODO: handle errno
|
||||
Ok((*_so_datalen) as usize)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn send(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
let len = ::std::cmp::min(buf.len(), c_int::max_value() as usize);
|
||||
@ -1219,6 +1256,24 @@ impl UdpSocketExt for UdpSocket {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "wasi")]
|
||||
fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let _ro_datalen: *mut sys::c::size_t = &mut 0;
|
||||
let _ro_flags: *mut sys::c::__wasi_roflags_t = &mut 0;
|
||||
unsafe {
|
||||
let _errno = __wasi_sock_recv(
|
||||
self.as_sock(),
|
||||
buf.as_mut_ptr() as *mut _,
|
||||
buf.len(),
|
||||
0,
|
||||
_ro_datalen,
|
||||
_ro_flags,
|
||||
);
|
||||
// TODO: handle errno
|
||||
Ok((*_ro_datalen) as usize)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let len = ::std::cmp::min(buf.len(), c_int::max_value() as usize);
|
||||
@ -1270,6 +1325,11 @@ fn set_nonblocking(sock: Socket, nonblocking: bool) -> io::Result<()> {
|
||||
}).map(|_| ())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "wasi")]
|
||||
fn set_nonblocking(_sock: Socket, _nonblocking: bool) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn set_nonblocking(sock: Socket, nonblocking: bool) -> io::Result<()> {
|
||||
let mut nonblocking = nonblocking as c_ulong;
|
||||
@ -1289,7 +1349,7 @@ fn ip2in_addr(ip: &Ipv4Addr) -> in_addr {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
fn ip2in_addr(ip: &Ipv4Addr) -> in_addr {
|
||||
let oct = ip.octets();
|
||||
in_addr {
|
||||
@ -1421,7 +1481,7 @@ impl TcpBuilder {
|
||||
|
||||
/// Set value for the `SO_REUSEADDR` option on this socket.
|
||||
///
|
||||
/// This indicates that futher calls to `bind` may allow reuse of local
|
||||
/// This indicates that further calls to `bind` may allow reuse of local
|
||||
/// addresses. For IPv4 sockets this means that a socket may bind even when
|
||||
/// there's a socket already listening on this port.
|
||||
pub fn reuse_address(&self, reuse: bool) -> io::Result<&Self> {
|
||||
|
9
third_party/rust/net2/src/lib.rs
vendored
9
third_party/rust/net2/src/lib.rs
vendored
@ -41,8 +41,12 @@
|
||||
html_root_url = "https://doc.rust-lang.org/net2-rs")]
|
||||
#![deny(missing_docs, warnings)]
|
||||
|
||||
// Silence warnings about deprecated try!() usage
|
||||
#![allow(deprecated)]
|
||||
|
||||
#[cfg(any(target_os="redox", unix))] extern crate libc;
|
||||
#![cfg_attr(target_os = "wasi", feature(wasi_ext))]
|
||||
|
||||
#[cfg(any(target_os = "redox", target_os = "wasi", unix))] extern crate libc;
|
||||
|
||||
#[cfg(windows)] extern crate winapi;
|
||||
|
||||
@ -63,7 +67,8 @@ mod utils;
|
||||
#[cfg(target_os="redox")] #[path = "sys/redox/mod.rs"] mod sys;
|
||||
#[cfg(unix)] #[path = "sys/unix/mod.rs"] mod sys;
|
||||
#[cfg(windows)] #[path = "sys/windows/mod.rs"] mod sys;
|
||||
#[cfg(all(unix, not(any(target_os = "solaris"))))] pub mod unix;
|
||||
#[cfg(target_os = "wasi")] #[path = "sys/wasi/mod.rs"] mod sys;
|
||||
#[cfg(all(unix, not(any(target_os = "solaris", target_os = "illumos"))))] pub mod unix;
|
||||
|
||||
pub use tcp::TcpBuilder;
|
||||
pub use udp::UdpBuilder;
|
||||
|
142
third_party/rust/net2/src/socket.rs
vendored
142
third_party/rust/net2/src/socket.rs
vendored
@ -12,9 +12,7 @@ use std::fmt;
|
||||
use std::io;
|
||||
use std::mem;
|
||||
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
|
||||
#[cfg(target_os = "redox")]
|
||||
use libc::c_int;
|
||||
#[cfg(unix)]
|
||||
#[cfg(any(unix, target_os = "redox", target_os = "wasi"))]
|
||||
use libc::c_int;
|
||||
#[cfg(windows)]
|
||||
use winapi::ctypes::c_int;
|
||||
@ -34,7 +32,7 @@ impl Socket {
|
||||
pub fn bind(&self, addr: &SocketAddr) -> io::Result<()> {
|
||||
let (addr, len) = addr2raw(addr);
|
||||
unsafe {
|
||||
::cvt(c::bind(self.inner.raw(), addr, len as c::socklen_t)).map(|_| ())
|
||||
::cvt(c::bind(self.inner.raw(), addr.as_ptr(), len as c::socklen_t)).map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,7 +45,7 @@ impl Socket {
|
||||
pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> {
|
||||
let (addr, len) = addr2raw(addr);
|
||||
unsafe {
|
||||
::cvt(c::connect(self.inner.raw(), addr, len)).map(|_| ())
|
||||
::cvt(c::connect(self.inner.raw(), addr.as_ptr(), len)).map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,17 +84,135 @@ impl ::IntoInner for Socket {
|
||||
fn into_inner(self) -> sys::Socket { self.inner }
|
||||
}
|
||||
|
||||
fn addr2raw(addr: &SocketAddr) -> (*const c::sockaddr, c::socklen_t) {
|
||||
match *addr {
|
||||
SocketAddr::V4(ref a) => {
|
||||
(a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t)
|
||||
}
|
||||
SocketAddr::V6(ref a) => {
|
||||
(a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t)
|
||||
}
|
||||
/// A type with the same memory layout as `c::sockaddr`. Used in converting Rust level
|
||||
/// SocketAddr* types into their system representation. The benefit of this specific
|
||||
/// type over using `c::sockaddr_storage` is that this type is exactly as large as it
|
||||
/// needs to be and not a lot larger.
|
||||
#[repr(C)]
|
||||
pub(crate) union SocketAddrCRepr {
|
||||
v4: c::sockaddr_in,
|
||||
v6: c::sockaddr_in6,
|
||||
}
|
||||
|
||||
impl SocketAddrCRepr {
|
||||
pub(crate) fn as_ptr(&self) -> *const c::sockaddr {
|
||||
self as *const _ as *const c::sockaddr
|
||||
}
|
||||
}
|
||||
|
||||
fn addr2raw(addr: &SocketAddr) -> (SocketAddrCRepr, c::socklen_t) {
|
||||
match addr {
|
||||
&SocketAddr::V4(ref v4) => addr2raw_v4(v4),
|
||||
&SocketAddr::V6(ref v6) => addr2raw_v6(v6),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn addr2raw_v4(addr: &SocketAddrV4) -> (SocketAddrCRepr, c::socklen_t) {
|
||||
let sin_addr = c::in_addr {
|
||||
s_addr: u32::from(*addr.ip()).to_be(),
|
||||
};
|
||||
|
||||
let sockaddr = SocketAddrCRepr {
|
||||
v4: c::sockaddr_in {
|
||||
sin_family: c::AF_INET as c::sa_family_t,
|
||||
sin_port: addr.port().to_be(),
|
||||
sin_addr,
|
||||
#[cfg(not(target_os = "haiku"))]
|
||||
sin_zero: [0; 8],
|
||||
#[cfg(target_os = "haiku")]
|
||||
sin_zero: [0; 24],
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "haiku",
|
||||
))]
|
||||
sin_len: 0,
|
||||
},
|
||||
};
|
||||
(sockaddr, mem::size_of::<c::sockaddr_in>() as c::socklen_t)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn addr2raw_v4(addr: &SocketAddrV4) -> (SocketAddrCRepr, c::socklen_t) {
|
||||
let sin_addr = unsafe {
|
||||
let mut s_un = mem::zeroed::<c::in_addr_S_un>();
|
||||
*s_un.S_addr_mut() = u32::from(*addr.ip()).to_be();
|
||||
c::IN_ADDR { S_un: s_un }
|
||||
};
|
||||
|
||||
let sockaddr = SocketAddrCRepr {
|
||||
v4: c::sockaddr_in {
|
||||
sin_family: c::AF_INET as c::sa_family_t,
|
||||
sin_port: addr.port().to_be(),
|
||||
sin_addr,
|
||||
sin_zero: [0; 8],
|
||||
},
|
||||
};
|
||||
(sockaddr, mem::size_of::<c::sockaddr_in>() as c::socklen_t)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn addr2raw_v6(addr: &SocketAddrV6) -> (SocketAddrCRepr, c::socklen_t) {
|
||||
let sin6_addr = {
|
||||
let mut sin6_addr = unsafe { mem::zeroed::<c::in6_addr>() };
|
||||
sin6_addr.s6_addr = addr.ip().octets();
|
||||
sin6_addr
|
||||
};
|
||||
|
||||
let sockaddr = SocketAddrCRepr {
|
||||
v6: c::sockaddr_in6 {
|
||||
sin6_family: c::AF_INET6 as c::sa_family_t,
|
||||
sin6_port: addr.port().to_be(),
|
||||
sin6_addr,
|
||||
sin6_flowinfo: addr.flowinfo(),
|
||||
sin6_scope_id: addr.scope_id(),
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "haiku",
|
||||
))]
|
||||
sin6_len: 0,
|
||||
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
|
||||
__sin6_src_id: 0,
|
||||
},
|
||||
};
|
||||
(sockaddr, mem::size_of::<c::sockaddr_in6>() as c::socklen_t)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn addr2raw_v6(addr: &SocketAddrV6) -> (SocketAddrCRepr, c::socklen_t) {
|
||||
let sin6_addr = unsafe {
|
||||
let mut u = mem::zeroed::<c::in6_addr_u>();
|
||||
*u.Byte_mut() = addr.ip().octets();
|
||||
c::IN6_ADDR { u }
|
||||
};
|
||||
let scope_id = unsafe {
|
||||
let mut u = mem::zeroed::<c::SOCKADDR_IN6_LH_u>();
|
||||
*u.sin6_scope_id_mut() = addr.scope_id();
|
||||
u
|
||||
};
|
||||
|
||||
let sockaddr = SocketAddrCRepr {
|
||||
v6: c::sockaddr_in6 {
|
||||
sin6_family: c::AF_INET6 as c::sa_family_t,
|
||||
sin6_port: addr.port().to_be(),
|
||||
sin6_addr,
|
||||
sin6_flowinfo: addr.flowinfo(),
|
||||
u: scope_id,
|
||||
},
|
||||
};
|
||||
(sockaddr, mem::size_of::<c::sockaddr_in6>() as c::socklen_t)
|
||||
}
|
||||
|
||||
fn raw2addr(storage: &c::sockaddr_storage, len: c::socklen_t) -> io::Result<SocketAddr> {
|
||||
match storage.ss_family as c_int {
|
||||
c::AF_INET => {
|
||||
|
8
third_party/rust/net2/src/sys/unix/mod.rs
vendored
8
third_party/rust/net2/src/sys/unix/mod.rs
vendored
@ -14,7 +14,7 @@ use std::mem;
|
||||
use std::net::{TcpListener, TcpStream, UdpSocket};
|
||||
use std::os::unix::io::FromRawFd;
|
||||
use libc::{self, c_int};
|
||||
#[cfg(not(any(target_os = "solaris", target_os = "emscripten")))]
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "haiku", target_os = "illumos", target_os = "solaris")))]
|
||||
use libc::{ioctl, FIOCLEX};
|
||||
|
||||
mod impls;
|
||||
@ -36,7 +36,7 @@ pub struct Socket {
|
||||
}
|
||||
|
||||
impl Socket {
|
||||
#[cfg(not(any(target_os = "solaris", target_os = "emscripten")))]
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "haiku", target_os = "illumos", target_os = "solaris")))]
|
||||
pub fn new(family: c_int, ty: c_int) -> io::Result<Socket> {
|
||||
unsafe {
|
||||
// Linux >2.6.26 overloads the type argument to accept SOCK_CLOEXEC,
|
||||
@ -56,9 +56,9 @@ impl Socket {
|
||||
}
|
||||
}
|
||||
|
||||
// ioctl(FIOCLEX) is not supported by Solaris/Illumos or emscripten,
|
||||
// ioctl(FIOCLEX) is not supported by Solaris/illumos or emscripten,
|
||||
// use fcntl(FD_CLOEXEC) instead
|
||||
#[cfg(any(target_os = "solaris", target_os = "emscripten"))]
|
||||
#[cfg(any(target_os = "emscripten", target_os = "haiku", target_os = "illumos", target_os = "solaris"))]
|
||||
pub fn new(family: c_int, ty: c_int) -> io::Result<Socket> {
|
||||
unsafe {
|
||||
let fd = try!(::cvt(libc::socket(family, ty, 0)));
|
||||
|
33
third_party/rust/net2/src/sys/wasi/impls.rs
vendored
Normal file
33
third_party/rust/net2/src/sys/wasi/impls.rs
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
use std::os::wasi::io::{FromRawFd, AsRawFd};
|
||||
|
||||
use {TcpBuilder, UdpBuilder, FromInner, AsInner};
|
||||
use socket::Socket;
|
||||
use sys::{self, c::__wasi_fd_t};
|
||||
|
||||
impl FromRawFd for TcpBuilder {
|
||||
unsafe fn from_raw_fd(fd: __wasi_fd_t) -> TcpBuilder {
|
||||
let sock = sys::Socket::from_inner(fd);
|
||||
TcpBuilder::from_inner(Socket::from_inner(sock))
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawFd for TcpBuilder {
|
||||
fn as_raw_fd(&self) -> __wasi_fd_t {
|
||||
// TODO: this unwrap() is very bad
|
||||
self.as_inner().borrow().as_ref().unwrap().as_inner().raw() as __wasi_fd_t
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRawFd for UdpBuilder {
|
||||
unsafe fn from_raw_fd(fd: __wasi_fd_t) -> UdpBuilder {
|
||||
let sock = sys::Socket::from_inner(fd);
|
||||
UdpBuilder::from_inner(Socket::from_inner(sock))
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawFd for UdpBuilder {
|
||||
fn as_raw_fd(&self) -> __wasi_fd_t {
|
||||
// TODO: this unwrap() is very bad
|
||||
self.as_inner().borrow().as_ref().unwrap().as_inner().raw() as __wasi_fd_t
|
||||
}
|
||||
}
|
185
third_party/rust/net2/src/sys/wasi/mod.rs
vendored
Normal file
185
third_party/rust/net2/src/sys/wasi/mod.rs
vendored
Normal file
@ -0,0 +1,185 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(non_camel_case_types)]
|
||||
use libc::{self, c_int, __wasi_fd_t};
|
||||
use std::io;
|
||||
use std::mem;
|
||||
use std::net::{TcpListener, TcpStream, UdpSocket};
|
||||
use std::os::wasi::io::FromRawFd;
|
||||
|
||||
mod impls;
|
||||
|
||||
pub mod c {
|
||||
pub use libc::*;
|
||||
|
||||
pub type sa_family_t = u16;
|
||||
pub type socklen_t = u32;
|
||||
pub type in_port_t = u16;
|
||||
|
||||
pub const SOCK_DGRAM: c_int = 0x00;
|
||||
pub const SOL_SOCKET: c_int = 0x00;
|
||||
pub const SO_RCVBUF: c_int = 0x00;
|
||||
pub const SO_SNDBUF: c_int = 0x00;
|
||||
pub const TCP_NODELAY: c_int = 0x00;
|
||||
pub const IPPROTO_TCP: c_int = 0x00;
|
||||
pub const SO_RCVTIMEO: c_int = 0x00;
|
||||
pub const SO_SNDTIMEO: c_int = 0x00;
|
||||
pub const IPPROTO_IP: c_int = 0x00;
|
||||
pub const IP_TTL: c_int = 0x00;
|
||||
pub const IPPROTO_IPV6: c_int = 0x00;
|
||||
pub const IPV6_V6ONLY: c_int = 0x00;
|
||||
pub const SO_ERROR: c_int = 0x00;
|
||||
pub const SO_LINGER: c_int = 0x00;
|
||||
pub const SO_BROADCAST: c_int = 0x00;
|
||||
pub const IP_MULTICAST_LOOP: c_int = 0x00;
|
||||
pub const IP_MULTICAST_TTL: c_int = 0x00;
|
||||
pub const IPV6_MULTICAST_HOPS: c_int = 0x00;
|
||||
pub const IPV6_MULTICAST_LOOP: c_int = 0x00;
|
||||
pub const IP_MULTICAST_IF: c_int = 0x00;
|
||||
pub const IPV6_MULTICAST_IF: c_int = 0x00;
|
||||
pub const IPV6_UNICAST_HOPS: c_int = 0x00;
|
||||
pub const IP_ADD_MEMBERSHIP: c_int = 0x00;
|
||||
pub const IPV6_ADD_MEMBERSHIP: c_int = 0x00;
|
||||
pub const IP_DROP_MEMBERSHIP: c_int = 0x00;
|
||||
pub const IPV6_DROP_MEMBERSHIP: c_int = 0x00;
|
||||
pub const SO_REUSEADDR: c_int = 0x00;
|
||||
pub const SOCK_STREAM: c_int = 0x00;
|
||||
pub const AF_INET: c_int = 0x00;
|
||||
pub const AF_INET6: c_int = 0x01;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct sockaddr_storage {
|
||||
pub ss_family: sa_family_t,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct sockaddr {
|
||||
pub sa_family: sa_family_t,
|
||||
pub sa_data: [c_char; 14],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct sockaddr_in6 {
|
||||
pub sin6_family: sa_family_t,
|
||||
pub sin6_port: in_port_t,
|
||||
pub sin6_flowinfo: u32,
|
||||
pub sin6_addr: in6_addr,
|
||||
pub sin6_scope_id: u32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct sockaddr_in {
|
||||
pub sin_family: sa_family_t,
|
||||
pub sin_port: in_port_t,
|
||||
pub sin_addr: in_addr,
|
||||
pub sin_zero: [u8; 8],
|
||||
}
|
||||
|
||||
#[repr(align(4))]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct in6_addr {
|
||||
pub s6_addr: [u8; 16],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct ipv6_mreq {
|
||||
pub ipv6mr_multiaddr: in6_addr,
|
||||
pub ipv6mr_interface: c_uint,
|
||||
}
|
||||
|
||||
pub type in_addr_t = u32;
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct in_addr {
|
||||
pub s_addr: in_addr_t,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct linger {
|
||||
pub l_onoff: c_int,
|
||||
pub l_linger: c_int,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct ip_mreq {
|
||||
pub imr_multiaddr: in_addr,
|
||||
pub imr_interface: in_addr,
|
||||
}
|
||||
|
||||
pub unsafe fn getsockname(_socket: __wasi_fd_t, _address: *mut sockaddr,
|
||||
_address_len: *mut socklen_t) -> c_int {
|
||||
unimplemented!()
|
||||
}
|
||||
pub unsafe fn connect(_socket: __wasi_fd_t, _address: *const sockaddr,
|
||||
_len: socklen_t) -> c_int {
|
||||
unimplemented!()
|
||||
}
|
||||
pub unsafe fn listen(_socket: __wasi_fd_t, _backlog: c_int) -> c_int {
|
||||
unimplemented!()
|
||||
}
|
||||
pub unsafe fn bind(_socket: __wasi_fd_t, _address: *const sockaddr,
|
||||
_address_len: socklen_t) -> c_int {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn sockaddr_in_u32(sa: &sockaddr_in) -> u32 {
|
||||
::ntoh((*sa).sin_addr.s_addr)
|
||||
}
|
||||
|
||||
pub fn in_addr_to_u32(addr: &in_addr) -> u32 {
|
||||
::ntoh(addr.s_addr)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Socket {
|
||||
fd: __wasi_fd_t,
|
||||
}
|
||||
|
||||
impl Socket {
|
||||
pub fn new(_family: c_int, _ty: c_int) -> io::Result<Socket> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> libc::__wasi_fd_t {
|
||||
self.fd
|
||||
}
|
||||
|
||||
fn into_fd(self) -> libc::__wasi_fd_t {
|
||||
let fd = self.fd;
|
||||
mem::forget(self);
|
||||
fd
|
||||
}
|
||||
|
||||
pub fn into_tcp_listener(self) -> TcpListener {
|
||||
unsafe { TcpListener::from_raw_fd(self.into_fd()) }
|
||||
}
|
||||
|
||||
pub fn into_tcp_stream(self) -> TcpStream {
|
||||
unsafe { TcpStream::from_raw_fd(self.into_fd()) }
|
||||
}
|
||||
|
||||
pub fn into_udp_socket(self) -> UdpSocket {
|
||||
unsafe { UdpSocket::from_raw_fd(self.into_fd()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl ::FromInner for Socket {
|
||||
type Inner = libc::__wasi_fd_t;
|
||||
fn from_inner(fd: libc::__wasi_fd_t) -> Socket {
|
||||
Socket { fd: fd }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Socket {
|
||||
fn drop(&mut self) {
|
||||
// unsafe {
|
||||
// let _ = libc::close(self.fd);
|
||||
// }
|
||||
}
|
||||
}
|
1
third_party/rust/net2/src/sys/windows/mod.rs
vendored
1
third_party/rust/net2/src/sys/windows/mod.rs
vendored
@ -34,6 +34,7 @@ pub mod c {
|
||||
pub use winapi::shared::ws2def::SOCKADDR as sockaddr;
|
||||
pub use winapi::shared::ws2def::SOCKADDR_STORAGE as sockaddr_storage;
|
||||
pub use winapi::shared::ws2def::SOCKADDR_IN as sockaddr_in;
|
||||
pub use winapi::shared::ws2def::ADDRESS_FAMILY as sa_family_t;
|
||||
pub use winapi::shared::ws2ipdef::*;
|
||||
pub use winapi::shared::ws2ipdef::SOCKADDR_IN6_LH as sockaddr_in6;
|
||||
pub use winapi::shared::ws2ipdef::IP_MREQ as ip_mreq;
|
||||
|
4
third_party/rust/net2/src/unix.rs
vendored
4
third_party/rust/net2/src/unix.rs
vendored
@ -10,7 +10,7 @@ use ext::{self, AsSock};
|
||||
pub trait UnixTcpBuilderExt {
|
||||
/// Set value for the `SO_REUSEPORT` option on this socket.
|
||||
///
|
||||
/// This indicates that futher calls to `bind` may allow reuse of local
|
||||
/// This indicates that further calls to `bind` may allow reuse of local
|
||||
/// addresses. For IPv4 sockets this means that a socket may bind even when
|
||||
/// there's a socket already listening on this port.
|
||||
fn reuse_port(&self, reuse: bool) -> io::Result<&Self>;
|
||||
@ -35,7 +35,7 @@ impl UnixTcpBuilderExt for TcpBuilder {
|
||||
pub trait UnixUdpBuilderExt {
|
||||
/// Set value for the `SO_REUSEPORT` option on this socket.
|
||||
///
|
||||
/// This indicates that futher calls to `bind` may allow reuse of local
|
||||
/// This indicates that further calls to `bind` may allow reuse of local
|
||||
/// addresses. For IPv4 sockets this means that a socket may bind even when
|
||||
/// there's a socket already listening on this port.
|
||||
fn reuse_port(&self, reuse: bool) -> io::Result<&Self>;
|
||||
|
45
third_party/rust/net2/tests/all.rs
vendored
45
third_party/rust/net2/tests/all.rs
vendored
@ -1,45 +0,0 @@
|
||||
extern crate net2;
|
||||
|
||||
use std::net::{TcpStream, IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
use std::io::prelude::*;
|
||||
use std::thread;
|
||||
|
||||
use net2::TcpBuilder;
|
||||
|
||||
macro_rules! t {
|
||||
($e:expr) => (match $e {
|
||||
Ok(e) => e,
|
||||
Err(e) => panic!("{} failed with: {}", stringify!($e), e),
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_build_listener() {
|
||||
let b = t!(TcpBuilder::new_v4());
|
||||
t!(b.bind("127.0.0.1:0"));
|
||||
|
||||
let addr = t!(b.local_addr());
|
||||
assert_eq!(addr.ip(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
|
||||
|
||||
let listener = t!(b.listen(200));
|
||||
|
||||
let t = thread::spawn(move || {
|
||||
let mut s = t!(listener.accept()).0;
|
||||
let mut b = [0; 4];
|
||||
t!(s.read(&mut b));
|
||||
assert_eq!(b, [1, 2, 3, 0]);
|
||||
});
|
||||
|
||||
let mut stream = t!(TcpStream::connect(&addr));
|
||||
t!(stream.write(&[1,2,3]));
|
||||
t.join().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_build_listener_v6() {
|
||||
let b = t!(TcpBuilder::new_v6());
|
||||
t!(b.bind("::1:0"));
|
||||
|
||||
let addr = t!(b.local_addr());
|
||||
assert_eq!(addr.ip(), IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)));
|
||||
}
|
Loading…
Reference in New Issue
Block a user