fix: 포트 충돌 회피 — note_bridge 8098, intent_service 8099
Jellyfin(8096), OrbStack(8097) 포트 충돌으로 변경. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
191
.venv/lib/python3.9/site-packages/qh3/quic/configuration.py
Normal file
191
.venv/lib/python3.9/site-packages/qh3/quic/configuration.py
Normal file
@@ -0,0 +1,191 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from os import PathLike
|
||||
from re import split
|
||||
from typing import TYPE_CHECKING, TextIO
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .._hazmat import Certificate as X509Certificate
|
||||
from .._hazmat import DsaPrivateKey, EcPrivateKey, Ed25519PrivateKey, RsaPrivateKey
|
||||
|
||||
from ..tls import (
|
||||
CipherSuite,
|
||||
SessionTicket,
|
||||
load_pem_private_key,
|
||||
load_pem_x509_certificates,
|
||||
)
|
||||
from .logger import QuicLogger
|
||||
from .packet import QuicProtocolVersion
|
||||
from .packet_builder import PACKET_MAX_SIZE
|
||||
|
||||
|
||||
@dataclass
|
||||
class QuicConfiguration:
|
||||
"""
|
||||
A QUIC configuration.
|
||||
"""
|
||||
|
||||
alpn_protocols: list[str] | None = None
|
||||
"""
|
||||
A list of supported ALPN protocols.
|
||||
"""
|
||||
|
||||
connection_id_length: int = 8
|
||||
"""
|
||||
The length in bytes of local connection IDs.
|
||||
"""
|
||||
|
||||
idle_timeout: float = 60.0
|
||||
"""
|
||||
The idle timeout in seconds.
|
||||
|
||||
The connection is terminated if nothing is received for the given duration.
|
||||
"""
|
||||
|
||||
is_client: bool = True
|
||||
"""
|
||||
Whether this is the client side of the QUIC connection.
|
||||
"""
|
||||
|
||||
max_data: int = 1048576
|
||||
"""
|
||||
Connection-wide flow control limit.
|
||||
"""
|
||||
|
||||
max_datagram_size: int = PACKET_MAX_SIZE
|
||||
"""
|
||||
The maximum QUIC payload size in bytes to send, excluding UDP or IP overhead.
|
||||
"""
|
||||
|
||||
probe_datagram_size: bool = True
|
||||
"""
|
||||
Enable path MTU discovery. Client-only.
|
||||
"""
|
||||
|
||||
max_stream_data: int = 1048576
|
||||
"""
|
||||
Per-stream flow control limit.
|
||||
"""
|
||||
|
||||
quic_logger: QuicLogger | None = None
|
||||
"""
|
||||
The :class:`~qh3.quic.logger.QuicLogger` instance to log events to.
|
||||
"""
|
||||
|
||||
secrets_log_file: TextIO = None
|
||||
"""
|
||||
A file-like object in which to log traffic secrets.
|
||||
|
||||
This is useful to analyze traffic captures with Wireshark.
|
||||
"""
|
||||
|
||||
server_name: str | None = None
|
||||
"""
|
||||
The server name to send during the TLS handshake the Server Name Indication.
|
||||
|
||||
.. note:: This is only used by clients.
|
||||
"""
|
||||
|
||||
session_ticket: SessionTicket | None = None
|
||||
"""
|
||||
The TLS session ticket which should be used for session resumption.
|
||||
"""
|
||||
|
||||
hostname_checks_common_name: bool = False
|
||||
assert_fingerprint: str | None = None
|
||||
verify_hostname: bool = True
|
||||
|
||||
cadata: bytes | None = None
|
||||
cafile: str | None = None
|
||||
capath: str | None = None
|
||||
|
||||
certificate: X509Certificate | None = None
|
||||
certificate_chain: list[X509Certificate] = field(default_factory=list)
|
||||
|
||||
cipher_suites: list[CipherSuite] | None = None
|
||||
initial_rtt: float = 0.1
|
||||
|
||||
max_datagram_frame_size: int | None = None
|
||||
original_version: int | None = None
|
||||
|
||||
private_key: (
|
||||
EcPrivateKey | Ed25519PrivateKey | DsaPrivateKey | RsaPrivateKey | None
|
||||
) = None
|
||||
|
||||
quantum_readiness_test: bool = False
|
||||
supported_versions: list[int] = field(
|
||||
default_factory=lambda: [
|
||||
QuicProtocolVersion.VERSION_1,
|
||||
QuicProtocolVersion.VERSION_2,
|
||||
]
|
||||
)
|
||||
verify_mode: int | None = None
|
||||
|
||||
def load_cert_chain(
|
||||
self,
|
||||
certfile: str | bytes | PathLike,
|
||||
keyfile: str | bytes | PathLike | None = None,
|
||||
password: bytes | str | None = None,
|
||||
) -> None:
|
||||
"""
|
||||
Load a private key and the corresponding certificate.
|
||||
"""
|
||||
|
||||
if isinstance(certfile, str):
|
||||
certfile = certfile.encode()
|
||||
elif isinstance(certfile, PathLike):
|
||||
certfile = str(certfile).encode()
|
||||
|
||||
if keyfile is not None:
|
||||
if isinstance(keyfile, str):
|
||||
keyfile = keyfile.encode()
|
||||
elif isinstance(keyfile, PathLike):
|
||||
keyfile = str(keyfile).encode()
|
||||
|
||||
# we either have the certificate or a file path in certfile/keyfile.
|
||||
if b"-----BEGIN" not in certfile:
|
||||
with open(certfile, "rb") as fp:
|
||||
certfile = fp.read()
|
||||
if keyfile is not None:
|
||||
with open(keyfile, "rb") as fp:
|
||||
keyfile = fp.read()
|
||||
|
||||
is_crlf = b"-----\r\n" in certfile
|
||||
boundary = (
|
||||
b"-----BEGIN PRIVATE KEY-----\n"
|
||||
if not is_crlf
|
||||
else b"-----BEGIN PRIVATE KEY-----\r\n"
|
||||
)
|
||||
chunks = split(b"\n" + boundary, certfile)
|
||||
|
||||
certificates = load_pem_x509_certificates(chunks[0])
|
||||
|
||||
if len(chunks) == 2:
|
||||
private_key = boundary + chunks[1]
|
||||
self.private_key = load_pem_private_key(private_key)
|
||||
|
||||
self.certificate = certificates[0]
|
||||
self.certificate_chain = certificates[1:]
|
||||
|
||||
if keyfile is not None:
|
||||
self.private_key = load_pem_private_key(
|
||||
keyfile,
|
||||
password=(
|
||||
password.encode("utf8") if isinstance(password, str) else password
|
||||
),
|
||||
)
|
||||
|
||||
def load_verify_locations(
|
||||
self,
|
||||
cafile: str | None = None,
|
||||
capath: str | None = None,
|
||||
cadata: bytes | None = None,
|
||||
) -> None:
|
||||
"""
|
||||
Load a set of "certification authority" (CA) certificates used to
|
||||
validate other peers' certificates.
|
||||
"""
|
||||
self.cafile = cafile
|
||||
self.capath = capath
|
||||
self.cadata = cadata
|
||||
Reference in New Issue
Block a user