Initial commit
This commit is contained in:
commit
5584446828
37 changed files with 7962 additions and 0 deletions
23
Sockets/INetStream.cs
Normal file
23
Sockets/INetStream.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Secucore
|
||||
*
|
||||
* Copyright (C) 2023 Trevor Hall
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license.
|
||||
*
|
||||
*/
|
||||
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SecuCore.Sockets
|
||||
{
|
||||
public interface INetStream
|
||||
{
|
||||
public Task<bool> WriteAsync(byte[] dat, int offset, int length);
|
||||
public Task<int> ReadAsync(byte[] dst, int offset, int length);
|
||||
public Task<byte[]> ReadUntilCRLF();
|
||||
public Task<byte[]> ReadUntilCRLFCRLF();
|
||||
}
|
||||
}
|
||||
266
Sockets/SecuredTCPStream.cs
Normal file
266
Sockets/SecuredTCPStream.cs
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* Secucore
|
||||
*
|
||||
* Copyright (C) 2023 Trevor Hall
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license.
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SecuCore.Sockets
|
||||
{
|
||||
public class SecuredTCPStream : INetStream
|
||||
{
|
||||
private TlsStream _tls;
|
||||
|
||||
public int recvBufferSize;
|
||||
private byte[] readBuffer;
|
||||
private int rbpos = 0;
|
||||
private int rbavail = 0;
|
||||
|
||||
public SecuredTCPStream(TCPSocket _tcps)
|
||||
{
|
||||
_tls = new TlsStream(_tcps);
|
||||
readBuffer = new byte[_tcps.RecvBufferSize];
|
||||
}
|
||||
|
||||
public void SetRecvBufferSize(int bufsz)
|
||||
{
|
||||
if (recvBufferSize != bufsz)
|
||||
{
|
||||
recvBufferSize = bufsz;
|
||||
byte[] recvbf = new byte[recvBufferSize];
|
||||
int copysz = readBuffer.Length;
|
||||
if (copysz > recvbf.Length) copysz = recvbf.Length;
|
||||
Buffer.BlockCopy(readBuffer, 0, recvbf, 0, copysz);
|
||||
readBuffer = recvbf;
|
||||
}
|
||||
}
|
||||
|
||||
private int FindCRLF(byte[] inbuf, int offset, int count)
|
||||
{
|
||||
for (int i = offset; i < offset + count - 1; i++)
|
||||
{
|
||||
if (inbuf[i] == 0x0d)
|
||||
{
|
||||
if (inbuf[i + 1] == 0x0a)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
private int FindCRLFCRLF(byte[] inbuf, int offset, int count)
|
||||
{
|
||||
for (int i = offset; i < offset + count - 3; i++)
|
||||
{
|
||||
if (inbuf[i] == 0x0d)
|
||||
{
|
||||
if (inbuf[i + 1] == 0x0a)
|
||||
{
|
||||
if (inbuf[i + 2] == 0x0d)
|
||||
{
|
||||
if (inbuf[i + 3] == 0x0a)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private async Task<bool> ReadAny()
|
||||
{
|
||||
rbavail = 0;
|
||||
rbpos = 0;
|
||||
int rlen = await _tls.ReadAsync(readBuffer, 0, readBuffer.Length).ConfigureAwait(false);
|
||||
if (rlen <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
rbavail = rlen;
|
||||
return true;
|
||||
}
|
||||
private async Task<int> ReadAsyncInternal(byte[] dest, int offset, int count)
|
||||
{
|
||||
if (rbavail == 0)
|
||||
{
|
||||
if (!await ReadAny().ConfigureAwait(false))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (rbavail > 0)
|
||||
{
|
||||
if (rbavail > count)
|
||||
{
|
||||
Buffer.BlockCopy(readBuffer, rbpos, dest, offset, count);
|
||||
rbpos += count;
|
||||
rbavail -= count;
|
||||
if (rbavail == 0) rbpos = 0;
|
||||
return count;
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer.BlockCopy(readBuffer, rbpos, dest, offset, rbavail);
|
||||
int read = rbavail;
|
||||
rbpos = 0;
|
||||
rbavail = 0;
|
||||
return read;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
public async Task<bool> NegotiateTLSConnection(string targetDomain, TLS.TLSRecordLayer.ValidateServerCertificate validationCallback, TLS.TLSRecordLayer.ClientCertificateRequest clientRequestCallback)
|
||||
{
|
||||
return await _tls.AuthenticateAsClientAsync(targetDomain, validationCallback, clientRequestCallback).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public Task<int> ReadAsync(byte[] dest)
|
||||
{
|
||||
return ReadAsyncInternal(dest, 0, dest.Length);
|
||||
}
|
||||
|
||||
public Task<int> ReadAsync(byte[] dest, int offset, int length)
|
||||
{
|
||||
return ReadAsyncInternal(dest, offset, length);
|
||||
}
|
||||
|
||||
public Task<int> ReadAsync(byte[] dest, CancellationToken token)
|
||||
{
|
||||
return ReadAsyncInternal(dest, 0, dest.Length);
|
||||
}
|
||||
public async Task<int> ReadAsync(Memory<byte> destmem, CancellationToken token)
|
||||
{
|
||||
byte[] localBuffer = new byte[destmem.Length];
|
||||
int len = await ReadAsyncInternal(localBuffer, 0, localBuffer.Length).ConfigureAwait(false);
|
||||
if (len > 0)
|
||||
{
|
||||
Memory<byte> lmem = new Memory<byte>(localBuffer, 0, len);
|
||||
lmem.CopyTo(destmem);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
public async Task<byte[]> ReadUntilCRLF()
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
int crlfi = -1;
|
||||
while (crlfi == -1)
|
||||
{
|
||||
if (rbavail == 0)
|
||||
{
|
||||
if (!await ReadAny().ConfigureAwait(false)) break;
|
||||
}
|
||||
crlfi = FindCRLF(readBuffer, rbpos, rbavail);
|
||||
//int resplen = ((crlfi + 2) - rbpos);
|
||||
|
||||
if (crlfi == -1)
|
||||
{
|
||||
await ms.WriteAsync(readBuffer, rbpos, rbavail).ConfigureAwait(false);
|
||||
rbavail = 0;
|
||||
rbpos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//we found crlf
|
||||
int sublen = (crlfi + 2) - rbpos;
|
||||
await ms.WriteAsync(readBuffer, rbpos, sublen).ConfigureAwait(false);
|
||||
rbavail -= sublen;
|
||||
rbpos += sublen;
|
||||
if (rbavail <= 0)
|
||||
{
|
||||
rbpos = 0;
|
||||
rbavail = 0;
|
||||
}
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
if (ms.Position == 0) return null;
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
public async Task<byte[]> ReadUntilCRLFCRLF()
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
int crlfi = -1;
|
||||
while (crlfi == -1)
|
||||
{
|
||||
if (rbavail == 0)
|
||||
{
|
||||
if (!await ReadAny().ConfigureAwait(false)) break;
|
||||
}
|
||||
crlfi = FindCRLFCRLF(readBuffer, rbpos, rbavail);
|
||||
int resplen = ((crlfi + 4) - rbpos);
|
||||
|
||||
if (crlfi == -1)
|
||||
{
|
||||
await ms.WriteAsync(readBuffer, rbpos, rbavail).ConfigureAwait(false);
|
||||
rbavail = 0;
|
||||
rbpos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//we found crlf
|
||||
await ms.WriteAsync(readBuffer, rbpos, resplen).ConfigureAwait(false);
|
||||
rbpos += resplen;
|
||||
rbavail -= resplen;
|
||||
if (rbavail <= 0)
|
||||
{
|
||||
rbpos = 0;
|
||||
rbavail = 0;
|
||||
}
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
if (ms.Position == 0) return null;
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
public async Task<bool> WriteAsync(byte[] dat)
|
||||
{
|
||||
await _tls.WriteAsync(dat).ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> WriteAsync(byte[] dat, int offset, int length)
|
||||
{
|
||||
await _tls.WriteAsync(dat, offset, length).ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> WriteAsync(ReadOnlyMemory<byte> datrom, CancellationToken token)
|
||||
{
|
||||
await _tls.WriteAsync(datrom.ToArray(), token).ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task DisposeAsync()
|
||||
{
|
||||
await _tls.DisposeAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
260
Sockets/TCPNetworkStream.cs
Normal file
260
Sockets/TCPNetworkStream.cs
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
* Secucore
|
||||
*
|
||||
* Copyright (C) 2023 Trevor Hall
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license.
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SecuCore.Sockets
|
||||
{
|
||||
public class TCPNetworkStream : INetStream
|
||||
{
|
||||
private static readonly byte[] crlfcrlf = new byte[] { 0x0d, 0x0a, 0x0d, 0x0a };
|
||||
private TCPSocket _tcpsocket;
|
||||
public int recvBufferSize;
|
||||
private byte[] readBuffer;
|
||||
private int rbpos = 0;
|
||||
private int rbavail = 0;
|
||||
|
||||
public TCPNetworkStream(TCPSocket tcpSocket)
|
||||
{
|
||||
_tcpsocket = tcpSocket;
|
||||
readBuffer = new byte[_tcpsocket.RecvBufferSize];
|
||||
recvBufferSize = _tcpsocket.RecvBufferSize;
|
||||
}
|
||||
public void SetRecvBufferSize(int bufsz)
|
||||
{
|
||||
if (recvBufferSize != bufsz)
|
||||
{
|
||||
recvBufferSize = bufsz;
|
||||
byte[] recvbf = new byte[recvBufferSize];
|
||||
int copysz = readBuffer.Length;
|
||||
if (copysz > recvbf.Length) copysz = recvbf.Length;
|
||||
Buffer.BlockCopy(readBuffer, 0, recvbf, 0, copysz);
|
||||
readBuffer = recvbf;
|
||||
}
|
||||
}
|
||||
|
||||
private int FindCRLF(byte[] inbuf, int offset, int count)
|
||||
{
|
||||
for (int i = offset; i < offset + count - 1; i++)
|
||||
{
|
||||
if (inbuf[i] == 0x0d && inbuf[i + 1] == 0x0a) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int FindCRLFCRLF(byte[] inbuf, int offset, int count)
|
||||
{
|
||||
for (int i = offset; i < offset + count - 3; i++)
|
||||
{
|
||||
bool match = true;
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
if ((inbuf[i + j] != crlfcrlf[j]))
|
||||
{
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (match) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private async Task<bool> ReadAny()
|
||||
{
|
||||
rbavail = 0;
|
||||
rbpos = 0;
|
||||
int rlen = await _tcpsocket.RecieveAsync(readBuffer, 0, readBuffer.Length).ConfigureAwait(false);
|
||||
if (rlen <= 0) return false;
|
||||
rbavail = rlen;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<int> ReadAsyncInternal(byte[] dest, int offset, int count)
|
||||
{
|
||||
if (rbavail == 0)
|
||||
{
|
||||
if (!await ReadAny().ConfigureAwait(false)) return 0;
|
||||
}
|
||||
|
||||
if (rbavail > 0)
|
||||
{
|
||||
if (rbavail > count)
|
||||
{
|
||||
Buffer.BlockCopy(readBuffer, rbpos, dest, offset, count);
|
||||
rbpos += count;
|
||||
rbavail -= count;
|
||||
if (rbavail == 0) rbpos = 0;
|
||||
return count;
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer.BlockCopy(readBuffer, rbpos, dest, offset, rbavail);
|
||||
int read = rbavail;
|
||||
rbpos = 0;
|
||||
rbavail = 0;
|
||||
return read;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<byte[]> ReadUntilCRLF()
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
int crlfi = -1;
|
||||
while (crlfi == -1)
|
||||
{
|
||||
if (rbavail == 0)
|
||||
{
|
||||
if (!await ReadAny().ConfigureAwait(false)) return null;
|
||||
}
|
||||
crlfi = FindCRLF(readBuffer, rbpos, rbavail);
|
||||
int resplen = ((crlfi+2) - rbpos);
|
||||
|
||||
if (crlfi == -1)
|
||||
{
|
||||
await ms.WriteAsync(readBuffer, rbpos, rbavail).ConfigureAwait(false);
|
||||
rbavail = 0;
|
||||
rbpos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//we found crlf
|
||||
await ms.WriteAsync(readBuffer, rbpos, resplen).ConfigureAwait(false);
|
||||
rbpos += resplen;
|
||||
rbavail -= resplen;
|
||||
if (rbavail <= 0)
|
||||
{
|
||||
rbpos = 0;
|
||||
rbavail = 0;
|
||||
}
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
if (ms.Position == 0) return null;
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<byte[]> ReadUntilCRLFCRLF()
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
int crlfi = -1;
|
||||
while (crlfi == -1)
|
||||
{
|
||||
if (rbavail == 0)
|
||||
{
|
||||
if (!await ReadAny().ConfigureAwait(false))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
crlfi = FindCRLFCRLF(readBuffer, rbpos, rbavail);
|
||||
int resplen = ((crlfi + 4) - rbpos);
|
||||
if (crlfi == -1)
|
||||
{
|
||||
await ms.WriteAsync(readBuffer, rbpos, rbavail).ConfigureAwait(false);
|
||||
rbavail = 0;
|
||||
rbpos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//we found crlf
|
||||
await ms.WriteAsync(readBuffer, rbpos, resplen).ConfigureAwait(false);
|
||||
rbpos += resplen;
|
||||
rbavail -= resplen;
|
||||
if (rbavail <= 0)
|
||||
{
|
||||
rbpos = 0;
|
||||
rbavail = 0;
|
||||
}
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
if (ms.Position == 0) return null;
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
private Task<bool> WriteAsyncInternal(byte[] buf)
|
||||
{
|
||||
return _tcpsocket.SendAsync(buf);
|
||||
}
|
||||
|
||||
public Task<bool> WriteAsync(ReadOnlyMemory<byte> datrom, CancellationToken token)
|
||||
{
|
||||
byte[] localCopy = datrom.ToArray();
|
||||
return _tcpsocket.SendAsync(localCopy);
|
||||
}
|
||||
|
||||
public Task<bool> WriteAsync(byte[] dat)
|
||||
{
|
||||
return WriteAsyncInternal(dat);
|
||||
}
|
||||
public Task<bool> WriteAsync(byte[] dat, int offset, int length)
|
||||
{
|
||||
if(dat.Length == length)
|
||||
{
|
||||
return _tcpsocket.SendAsync(dat);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] localCopy = new byte[length];
|
||||
Buffer.BlockCopy(dat, offset, localCopy, 0, length);
|
||||
return _tcpsocket.SendAsync(localCopy);
|
||||
}
|
||||
}
|
||||
|
||||
public Task<int> ReadAsync(byte[] dest)
|
||||
{
|
||||
return ReadAsyncInternal(dest, 0, dest.Length);
|
||||
}
|
||||
|
||||
public Task<int> ReadAsync(byte[] dest, int offset, int length)
|
||||
{
|
||||
return ReadAsyncInternal(dest, offset, length);
|
||||
}
|
||||
|
||||
public Task<int> ReadAsync(byte[] dest, CancellationToken token)
|
||||
{
|
||||
return ReadAsyncInternal(dest, 0, dest.Length);
|
||||
}
|
||||
public async Task<int> ReadAsync(Memory<byte> destmem, CancellationToken token)
|
||||
{
|
||||
byte[] localBuffer = new byte[destmem.Length];
|
||||
int len = await ReadAsyncInternal(localBuffer, 0, localBuffer.Length);
|
||||
if (len > 0)
|
||||
{
|
||||
Memory<byte> lmem = new Memory<byte>(localBuffer, 0, len);
|
||||
lmem.CopyTo(destmem);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
readBuffer = null;
|
||||
_tcpsocket = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
208
Sockets/TCPSocket.cs
Normal file
208
Sockets/TCPSocket.cs
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* Secucore
|
||||
*
|
||||
* Copyright (C) 2023 Trevor Hall
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license.
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SecuCore.Proxies;
|
||||
namespace SecuCore.Sockets
|
||||
{
|
||||
public class TCPSocket
|
||||
{
|
||||
private Socket _socket;
|
||||
private Proxy _proxy;
|
||||
private TCPNetworkStream _tcpns;
|
||||
private string _remoteHost;
|
||||
private int _remotePort;
|
||||
public int connectionLevelReached = 0;
|
||||
public int ConnectTimeout { get; set; } = 10000;
|
||||
public int WriteTimeout { get; set; } = 10000;
|
||||
public int ReadTimeout { get; set; } = 10000;
|
||||
public bool NoDelay { get; set; } = false;
|
||||
private int _socketRBS = 0;
|
||||
private int _socketSBS = 0;
|
||||
private int _recvBufSz = 0;
|
||||
private int _sendBufSz = 0;
|
||||
public int SendBufferSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return _sendBufSz;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != _sendBufSz)
|
||||
{
|
||||
_sendBufSz = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
public int RecvBufferSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return _recvBufSz;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != _recvBufSz)
|
||||
{
|
||||
_recvBufSz = value;
|
||||
if (_tcpns != null)
|
||||
{
|
||||
_tcpns.SetRecvBufferSize(_recvBufSz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public bool ResetOnClose { get; set; } = false;
|
||||
public TCPSocket(string remoteHost, int remotePort, Proxy proxy = null, int wsaSockRecieveBufferSize = 8192, int wsaSockSendBufferSize = 8192)
|
||||
{
|
||||
_remoteHost = remoteHost;
|
||||
_remotePort = remotePort;
|
||||
_proxy = proxy;
|
||||
_socketRBS = wsaSockRecieveBufferSize;
|
||||
_socketSBS = wsaSockSendBufferSize;
|
||||
_recvBufSz = wsaSockRecieveBufferSize;
|
||||
_sendBufSz = wsaSockSendBufferSize;
|
||||
}
|
||||
public void SetWSASockBufferSizes(int recieve, int send)
|
||||
{
|
||||
if (_socket != null)
|
||||
{
|
||||
_socket.ReceiveBufferSize = recieve;
|
||||
_socket.SendBufferSize = send;
|
||||
}
|
||||
}
|
||||
public void SetProxy(string proxyStr, ProxyProtocol protocol)
|
||||
{
|
||||
try
|
||||
{
|
||||
this._proxy = new Proxy(proxyStr, protocol);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ArgumentException(e.Message);
|
||||
}
|
||||
}
|
||||
public void SetTimeout(int milliseconds)
|
||||
{
|
||||
ConnectTimeout = milliseconds;
|
||||
WriteTimeout = milliseconds;
|
||||
ReadTimeout = milliseconds;
|
||||
}
|
||||
public TCPNetworkStream GetStream()
|
||||
{
|
||||
if (_tcpns == null) _tcpns = new TCPNetworkStream(this);
|
||||
return _tcpns;
|
||||
}
|
||||
public bool Connected() => _socket.Connected;
|
||||
public async Task<bool> ConnectAsync()
|
||||
{
|
||||
using (CancellationTokenSource cts = new CancellationTokenSource())
|
||||
{
|
||||
try
|
||||
{
|
||||
bool usingProxy = (_proxy != null);
|
||||
if (!IPAddress.TryParse(_remoteHost, out IPAddress rhip))
|
||||
{
|
||||
string remoteip = await DNS.AsyncDNSResolver.GetFirstArecord(_remoteHost);
|
||||
if (!IPAddress.TryParse(remoteip, out rhip))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_remoteHost = rhip.ToString();
|
||||
}
|
||||
IPEndPoint ipep = (usingProxy ? _proxy.GetRemoteEndpoint() : new IPEndPoint(rhip, _remotePort));
|
||||
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
_socket.ReceiveTimeout = this.ReadTimeout;
|
||||
_socket.SendTimeout = this.WriteTimeout;
|
||||
_socket.NoDelay = this.NoDelay;
|
||||
_socket.ReceiveBufferSize = _socketRBS;
|
||||
_socket.SendBufferSize = _socketSBS;
|
||||
if (ResetOnClose) _socket.LingerState = new LingerOption(true, 0);
|
||||
Task delayTask = Task.Delay(ConnectTimeout, cts.Token);
|
||||
Task conTask = _socket.ConnectAsync(ipep, cts.Token).AsTask();
|
||||
Task ret = await Task.WhenAny(conTask, delayTask).ConfigureAwait(false);
|
||||
cts.Cancel();
|
||||
if (ret == delayTask) return false;
|
||||
if (_socket.Connected)
|
||||
{
|
||||
_socket.NoDelay = this.NoDelay;
|
||||
connectionLevelReached = 1;
|
||||
if (usingProxy)
|
||||
{
|
||||
bool proxyconres = await _proxy.ConnectAsync(GetStream(), _remoteHost, _remotePort).ConfigureAwait(false);
|
||||
if (proxyconres) connectionLevelReached = 2;
|
||||
return proxyconres;
|
||||
}
|
||||
else
|
||||
{
|
||||
connectionLevelReached = 2;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{ }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public virtual async Task<bool> SendAsync(byte[] data)
|
||||
{
|
||||
using (CancellationTokenSource cts = new CancellationTokenSource(WriteTimeout))
|
||||
{
|
||||
ReadOnlyMemory<byte> rom = new ReadOnlyMemory<byte>(data, 0, data.Length);
|
||||
try
|
||||
{
|
||||
int remain = data.Length;
|
||||
while (remain > 0)
|
||||
{
|
||||
int sentdata = await _socket.SendAsync(rom, SocketFlags.None, cts.Token).ConfigureAwait(false);
|
||||
if (sentdata <= 0) return false;
|
||||
remain -= sentdata;
|
||||
if (remain <= 0) return true;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{ }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public virtual async Task<int> RecieveAsync(byte[] dest, int offset, int count)
|
||||
{
|
||||
Memory<byte> mem = new Memory<byte>(dest, offset, count);
|
||||
try
|
||||
{
|
||||
using (CancellationTokenSource cts = new CancellationTokenSource(ReadTimeout))
|
||||
{
|
||||
return await _socket.ReceiveAsync(mem, SocketFlags.None, cts.Token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{ }
|
||||
return 0;
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
if (ResetOnClose)
|
||||
{
|
||||
if (_socket != null) _socket.Close(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_socket.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue