add error sets to tcpConnect* and tls.Client.init

This commit is contained in:
Nameless 2023-03-06 20:11:56 -06:00
parent afb26f4e6b
commit 8d86194b6e
No known key found for this signature in database
GPG Key ID: A477BC03CAFCCAF7
2 changed files with 80 additions and 4 deletions

View File

@ -88,11 +88,59 @@ pub const StreamInterface = struct {
}
};
pub fn InitError(comptime Stream: type) type {
return std.mem.Allocator.Error || Stream.WriteError || Stream.ReadError || error {
InsufficientEntropy,
DiskQuota,
LockViolation,
NotOpenForWriting,
TlsAlert,
TlsUnexpectedMessage,
TlsIllegalParameter,
TlsDecryptFailure,
TlsRecordOverflow,
TlsBadRecordMac,
CertificateFieldHasInvalidLength,
CertificateHostMismatch,
CertificatePublicKeyInvalid,
CertificateExpired,
CertificateFieldHasWrongDataType,
CertificateIssuerMismatch,
CertificateNotYetValid,
CertificateSignatureAlgorithmMismatch,
CertificateSignatureAlgorithmUnsupported,
CertificateSignatureInvalid,
CertificateSignatureInvalidLength,
CertificateSignatureNamedCurveUnsupported,
CertificateSignatureUnsupportedBitCount,
TlsCertificateNotVerified,
TlsBadSignatureScheme,
TlsBadRsaSignatureBitCount,
InvalidEncoding,
IdentityElement,
SignatureVerificationFailed,
TlsDecryptError,
TlsConnectionTruncated,
TlsDecodeError,
UnsupportedCertificateVersion,
CertificateTimeInvalid,
CertificateHasUnrecognizedObjectId,
CertificateHasInvalidBitString,
MessageTooLong,
NegativeIntoUnsigned,
TargetTooSmall,
BufferTooSmall,
InvalidSignature,
NotSquare,
NonCanonical,
};
}
/// Initiates a TLS handshake and establishes a TLSv1.3 session with `stream`, which
/// must conform to `StreamInterface`.
///
/// `host` is only borrowed during this function call.
pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) !Client {
pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) InitError(@TypeOf(stream))!Client {
const host_len = @intCast(u16, host.len);
var random_buffer: [128]u8 = undefined;

View File

@ -702,8 +702,10 @@ pub const AddressList = struct {
}
};
pub const TcpConnectToHostError = GetAddressListError || TcpConnectToAddressError;
/// All memory allocated with `allocator` will be freed before this function returns.
pub fn tcpConnectToHost(allocator: mem.Allocator, name: []const u8, port: u16) !Stream {
pub fn tcpConnectToHost(allocator: mem.Allocator, name: []const u8, port: u16) TcpConnectToHostError!Stream {
const list = try getAddressList(allocator, name, port);
defer list.deinit();
@ -720,7 +722,9 @@ pub fn tcpConnectToHost(allocator: mem.Allocator, name: []const u8, port: u16) !
return std.os.ConnectError.ConnectionRefused;
}
pub fn tcpConnectToAddress(address: Address) !Stream {
pub const TcpConnectToAddressError = std.os.SocketError || std.os.ConnectError;
pub fn tcpConnectToAddress(address: Address) TcpConnectToAddressError!Stream {
const nonblock = if (std.io.is_async) os.SOCK.NONBLOCK else 0;
const sock_flags = os.SOCK.STREAM | nonblock |
(if (builtin.target.os.tag == .windows) 0 else os.SOCK.CLOEXEC);
@ -737,8 +741,32 @@ pub fn tcpConnectToAddress(address: Address) !Stream {
return Stream{ .handle = sockfd };
}
const GetAddressListError = std.mem.Allocator.Error || std.fs.File.OpenError || std.fs.File.ReadError || std.os.SocketError || std.os.BindError || error {
// TODO: break this up into error sets from the various underlying functions
TemporaryNameServerFailure,
NameServerFailure,
AddressFamilyNotSupported,
UnknownHostName,
ServiceUnavailable,
Unexpected,
HostLacksNetworkAddresses,
InvalidCharacter,
InvalidEnd,
NonCanonical,
Overflow,
Incomplete,
InvalidIpv4Mapping,
InvalidIPAddressFormat,
InterfaceNotFound,
FileSystem,
};
/// Call `AddressList.deinit` on the result.
pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*AddressList {
pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) GetAddressListError!*AddressList {
const result = blk: {
var arena = std.heap.ArenaAllocator.init(allocator);
errdefer arena.deinit();