use std::ptr;
use std::sync::Arc;
use std::task::Waker;
use std::time::Duration;
use std::net::SocketAddr;
use std::cell::UnsafeCell;
use std::result::Result as GenResult;
use std::io::{Error, Result, ErrorKind};
use std::sync::atomic::{AtomicU8, Ordering};
use futures::future::LocalBoxFuture;
use quinn_proto::{ConnectionHandle, ConnectionEvent, Dir, StreamId, Transmit};
use crossbeam_channel::Sender;
use crossbeam_utils::atomic::AtomicCell;
use bytes::BytesMut;
use pi_async_rt::{lock::spin_lock::SpinLock,
rt::{AsyncValue,
serial_local_thread::LocalTaskRuntime}};
use udp::SocketHandle as UdpSocketHandle;
pub mod acceptor;
pub mod connect;
pub mod connect_pool;
pub mod server;
pub mod client;
pub mod utils;
use crate::connect::QuicSocket;
use crate::utils::{QuicSocketStatus, QuicSocketReady, Hibernate, ContextHandle};
pub trait AsyncService: Send + Sync + 'static {
fn handle_connected(&self,
handle: SocketHandle,
result: Result<()>) -> LocalBoxFuture<'static, ()>;
fn handle_opened_expanding_stream(&self,
handle: SocketHandle,
stream_id: StreamId,
stream_type: Dir,
result: Result<()>) -> LocalBoxFuture<'static, ()>;
fn handle_readed(&self,
handle: SocketHandle,
stream_id: StreamId,
result: Result<usize>) -> LocalBoxFuture<'static, ()>;
fn handle_writed(&self,
handle: SocketHandle,
stream_id: StreamId,
result: Result<()>) -> LocalBoxFuture<'static, ()>;
fn handle_closed(&self,
handle: SocketHandle,
stream_id: Option<StreamId>,
code: u32,
result: Result<()>) -> LocalBoxFuture<'static, ()>;
fn handle_timeouted(&self,
handle: SocketHandle,
result: Result<SocketEvent>) -> LocalBoxFuture<'static, ()>;
}
pub struct SocketHandle(Arc<InnerSocketHandle>);
unsafe impl Send for SocketHandle {}
unsafe impl Sync for SocketHandle {}
impl Clone for SocketHandle {
fn clone(&self) -> Self {
SocketHandle(self.0.clone())
}
}
impl SocketHandle {
pub fn new(uid: usize,
status: Arc<AtomicU8>,
socket: Arc<UnsafeCell<QuicSocket>>,
local: SocketAddr,
remote: SocketAddr,
sender: Sender<QuicEvent>) -> Self {
let inner = InnerSocketHandle {
uid,
status,
inner: socket,
local: AtomicCell::new(local),
remote,
sender,
};
SocketHandle(Arc::new(inner))
}
pub fn broadcast(handles: &[SocketHandle],
payload: Vec<u8>) -> Result<()> {
if handles.len() == 0 {
return Ok(());
}
for handle in handles {
for stream_id in handle.get_stream_ids() {
handle.write_ready(stream_id, payload.clone())?;
}
}
Ok(())
}
pub fn get_uid(&self) -> usize {
self.0.uid
}
pub fn get_status(&self) -> QuicSocketStatus {
self
.0
.status
.load(Ordering::Acquire)
.into()
}
pub fn get_local_udp(&self) -> &SocketAddr {
unsafe {
(&*self.0.inner.get())
.get_udp_handle()
.get_local()
}
}
pub fn get_remote_udp(&self) -> Option<&SocketAddr> {
unsafe {
(&*self.0.inner.get())
.get_udp_handle()
.get_remote()
}
}
pub fn get_local(&self) -> SocketAddr {
self
.0
.local
.load()
}
pub fn set_local(&self, local: SocketAddr) {
self
.0
.local
.store(local);
}
pub fn get_remote(&self) -> SocketAddr {
self.0.remote
}
pub fn get_udp_uid(&self) -> usize {
unsafe {
(&*self.0.inner.get()).get_udp_handle().get_uid()
}
}
pub fn is_client(&self) -> bool {
unsafe {
(&*self.0.inner.get()).is_client()
}
}
pub fn get_connection_handle(&self) -> &ConnectionHandle {
unsafe {
(&*self.0.inner.get()).get_connection_handle()
}
}
pub fn get_session<T>(&self) -> Option<ContextHandle<T>> {
unsafe {
(&*(&*self.0.inner.get()).get_context().get()).get::<T>()
}
}
pub fn set_session<T>(&self, context: T) {
unsafe {
(&mut *(&*self.0.inner.get()).get_context().get()).set::<T>(context);
}
}
pub fn remove_session<T>(&self) -> Result<Option<T>> {
unsafe {
match (&mut *(&*self.0.inner.get()).get_context().get()).remove::<T>() {
Err(e) => Err(Error::new(ErrorKind::Other, e)),
Ok(r) => Ok(r)
}
}
}
pub fn is_0rtt(&self) -> bool {
unsafe {
(&*self.0.inner.get()).is_0rtt()
}
}
pub fn is_closed(&self) -> bool {
unsafe {
(&*self.0.inner.get()).is_closed()
}
}
pub fn get_latency(&self) -> Duration {
unsafe {
(&*self.0.inner.get()).get_latency()
}
}
pub fn get_main_stream_id(&self) -> Option<&StreamId> {
unsafe {
(&*self.0.inner.get()).get_main_stream_id()
}
}
pub(crate) fn open_main_streams(&self) -> Result<()> {
unsafe {
(&mut *self.0.inner.get()).open_main_streams()
}
}
pub async fn open_expanding_stream(&self, stream_type: Dir) -> Result<StreamId> {
unsafe {
(&*self.0.inner.get()).open_expanding_stream(stream_type).await
}
}
pub fn set_ready(&self,
stream_id: StreamId,
ready: QuicSocketReady) {
unsafe {
(&*self.0.inner.get()).set_ready(stream_id, ready);
}
}
pub fn get_stream_ids(&self) -> Vec<StreamId> {
unsafe {
(&*self.0.inner.get()).get_stream_ids()
}
}
pub fn read_ready(&self,
stream_id: &StreamId,
adjust: usize) -> GenResult<AsyncValue<usize>, usize> {
unsafe {
(&mut *self.0.inner.get()).read_ready(stream_id, adjust)
}
}
pub fn read_buffer_remaining(&self, stream_id: &StreamId) -> Option<usize> {
unsafe {
(&*self.0.inner.get()).read_buffer_remaining(stream_id)
}
}
pub fn get_read_buffer(&self,
stream_id: &StreamId) -> Option<Arc<SpinLock<Option<BytesMut>>>> {
unsafe {
(&*self.0.inner.get()).get_read_buffer(stream_id)
}
}
pub fn write_ready<B>(&self,
stream_id: StreamId,
buf: B) -> Result<()>
where B: AsRef<[u8]> + 'static {
unsafe {
(&*self.0.inner.get()).write_ready(stream_id, buf)
}
}
pub fn set_timeout(&self, timeout: usize, event: SocketEvent) {
unsafe {
(&*self.0.inner.get()).set_timeout(timeout, event);
}
}
pub fn unset_timeout(&self) {
unsafe {
(&*self.0.inner.get()).unset_timeout();
}
}
pub fn run_hibernated_tasks(&self) {
unsafe {
(&*self.0.inner.get()).run_hibernated_tasks();
}
}
pub fn hibernate(&self,
stream_id: StreamId,
ready: QuicSocketReady) -> Option<Hibernate> {
unsafe {
(&*self.0.inner.get()).hibernate(self.clone(),
stream_id,
ready)
}
}
pub fn set_hibernate(&self, hibernate: Hibernate) -> bool {
unsafe {
(&*self.0.inner.get()).set_hibernate(hibernate)
}
}
pub fn set_hibernate_wakers(&self, waker: Waker) {
unsafe {
(&*self.0.inner.get()).set_hibernate_wakers(waker);
}
}
pub fn wakeup(&self, result: Result<()>) -> bool {
unsafe {
(&mut *self.0.inner.get()).wakeup(result)
}
}
pub fn get_runtime(&self) -> Option<LocalTaskRuntime<()>> {
unsafe {
(&*self.0.inner.get()).get_runtime()
}
}
pub fn spawn(&self, task: LocalBoxFuture<'static, ()>) {
unsafe {
(&*self.0.inner.get()).spawn(task);
}
}
pub fn close_expanding_stream(&self, stream_id: StreamId) -> Result<()> {
unsafe {
(&*self.0.inner.get()).close_expanding_stream(stream_id)
}
}
pub fn close(&self, code: u32, reason: Result<()>) -> Result<()> {
unsafe {
(&mut *self.0.inner.get()).close(code, reason)
}
}
pub fn force_close(&mut self, code: u32, reason: String) {
unsafe {
(&mut *self.0.inner.get()).force_close(code, reason);
}
}
}
struct InnerSocketHandle {
uid: usize, status: Arc<AtomicU8>, inner: Arc<UnsafeCell<QuicSocket>>, local: AtomicCell<SocketAddr>, remote: SocketAddr, sender: Sender<QuicEvent>, }
#[derive(Debug)]
pub struct SocketEvent {
inner: *mut (), }
unsafe impl Send for SocketEvent {}
impl SocketEvent {
pub fn empty() -> Self {
SocketEvent {
inner: ptr::null_mut(),
}
}
pub fn is_empty(&self) -> bool {
self.inner.is_null()
}
pub fn get<T: 'static>(&self) -> Option<T> {
if self.is_empty() {
return None;
}
Some(unsafe { *Box::from_raw(self.inner as *mut T) })
}
pub fn set<T: 'static>(&mut self, event: T) -> bool {
if !self.is_empty() {
return false;
}
self.inner = Box::into_raw(Box::new(event)) as *mut ();
true
}
pub fn remove<T: 'static>(&mut self) -> Option<T> {
if self.is_empty() {
return None;
}
let result = self.get();
self.inner = ptr::null_mut();
result
}
}
#[derive(Debug)]
pub enum QuicEvent {
Accepted(QuicSocket), ConnectionReceived(ConnectionHandle, ConnectionEvent), ConnectionSend(ConnectionHandle, Transmit), StreamOpen(ConnectionHandle, Dir, AsyncValue<Result<StreamId>>), StreamReady(ConnectionHandle, StreamId, QuicSocketReady), StreamWrite(ConnectionHandle, StreamId, Vec<u8>), RebindUdp(UdpSocketHandle), Timeout(ConnectionHandle, Option<(usize, SocketEvent)>), StreamClose(ConnectionHandle, Option<StreamId>, u32), ConnectionClose(ConnectionHandle), }