private void ApplyConfiguration(IntPtr config) { if (ApplicationProtocols.Count > 0) { // Build a single buffer that is a set of non-empty 8-bit length prefixed strings: // For example "\x08http/1.1\x08http/0.9" var totalLength = ApplicationProtocols.Count + ApplicationProtocols.Sum(p => p.Value.Length); // PERF: Could probably stackalloc this if it's small enough // I believe quiche copies the data out as soon as the function is called, so it's safe to do so. var buf = new byte[totalLength]; var offset = 0; foreach (var protocol in ApplicationProtocols) { if (protocol.Value.Length > byte.MaxValue) { var protocolName = Encoding.UTF8.GetString(protocol.Value.ToArray()); var message = $"Application Protocol value is too long: {protocolName}"; throw new InvalidOperationException(message); } buf[offset] = (byte)protocol.Value.Length; protocol.Value.CopyTo(buf.AsMemory(offset + 1)); offset += protocol.Value.Length + 1; } // Set the value on the internal config struct var err = NativeMethods.quiche_config_set_application_protos(config, buf, (UIntPtr)buf.Length); if (err != 0) { throw QuicheException.FromErrorCode((QuicheErrorCode)err); } } NativeMethods.quiche_config_verify_peer(config, VerifyPeerCertificate); NativeMethods.quiche_config_grease(config, EnableTlsGrease); NativeMethods.quiche_config_set_disable_active_migration(config, !AllowActiveMigration); if (EnableSslKeyLogging) { NativeMethods.quiche_config_log_keys(config); } if (EnableEarlyData) { NativeMethods.quiche_config_enable_early_data(config); } if (IdleTimeout != TimeSpan.Zero) { NativeMethods.quiche_config_set_idle_timeout(config, (long)IdleTimeout.TotalMilliseconds); } if (MaxPacketSize != null) { NativeMethods.quiche_config_set_max_packet_size(config, MaxPacketSize.Value); } if (InitialMaxData != null) { NativeMethods.quiche_config_set_initial_max_data(config, InitialMaxData.Value); } if (InitialMaxStreamDataBiDiLocal != null) { NativeMethods.quiche_config_set_initial_max_stream_data_bidi_local(config, InitialMaxStreamDataBiDiLocal.Value); } if (InitialMaxStreamDataBiDiRemote != null) { NativeMethods.quiche_config_set_initial_max_stream_data_bidi_remote(config, InitialMaxStreamDataBiDiRemote.Value); } if (InitialMaxStreamDataUni != null) { NativeMethods.quiche_config_set_initial_max_stream_data_uni(config, InitialMaxStreamDataUni.Value); } if (InitialMaxStreamsBidi != null) { NativeMethods.quiche_config_set_initial_max_streams_bidi(config, InitialMaxStreamsBidi.Value); } if (InitialMaxStreamsUni != null) { NativeMethods.quiche_config_set_initial_max_streams_uni(config, InitialMaxStreamsUni.Value); } if (AckDelayExponent != null) { NativeMethods.quiche_config_set_ack_delay_exponent(config, AckDelayExponent.Value); } if (MaxAckDelay != null) { NativeMethods.quiche_config_set_max_ack_delay(config, MaxAckDelay.Value); } }
public QuicheConfigBuilder AddApplicationProtocol(TlsApplicationProtocol protocol) { ApplicationProtocols.Add(protocol); return(this); }