public async Task <WtcSocket> WideClientConnectAsync(string pcid, WideTunnelClientOptions clientOptions, bool noCache, CancellationToken cancel = default) { bool retryFlag = false; L_RETRY: WtConnectParam connectParam = await WideClientConnectInnerAsync(pcid, clientOptions, noCache, cancel); $"WideClientConnect: pcid {pcid}: Redirecting to {connectParam.HostName}:{connectParam.Port} (CacheUsed = {connectParam.CacheUsed}) ..."._Debug(); try { ConnSock tcpSock = await this.TcpIp.ConnectAsync(new TcpConnectParam(connectParam.HostName, connectParam.Port, AddressFamily.InterNetwork, connectTimeout : CoresConfig.WtcConfig.WpcTimeoutMsec, dnsTimeout : CoresConfig.WtcConfig.WpcTimeoutMsec), cancel); try { ConnSock targetSock = tcpSock; try { PalSslClientAuthenticationOptions sslOptions = new PalSslClientAuthenticationOptions(connectParam.HostName, false, (cert) => this.CheckValidationCallback(this, cert.NativeCertificate, null, SslPolicyErrors.None)); SslSock sslSock = new SslSock(tcpSock); try { await sslSock.StartSslClientAsync(sslOptions, cancel); targetSock = sslSock; } catch { await sslSock._DisposeSafeAsync(); throw; } WtcSocket wtcSocket = new WtcSocket(targetSock, new WtcOptions(this, connectParam)); await wtcSocket.StartWtcAsync(cancel); return(wtcSocket); } catch { await targetSock._DisposeSafeAsync(); throw; } } catch { await tcpSock._DisposeSafeAsync(); throw; } } catch { if (connectParam.CacheUsed && retryFlag == false) { retryFlag = true; // 接続キャッシュを使用して接続することに失敗した // 場合はキャッシュを消去して再試行する WideTunnel.ConnectParamCache.Delete(pcid); $"WideClientConnect: pcid {pcid}: Connect with Session Cache Failed. Retrying..."._Debug(); goto L_RETRY; } throw; } }
async Task <WtConnectParam> WideClientConnectInnerAsync(string pcid, WideTunnelClientOptions clientOptions, bool noCache, CancellationToken cancel = default) { if (noCache == false) { WtConnectParam?cached = ConnectParamCache[pcid]; if (cached != null) { var ret = cached._CloneDeep(); ret.CacheUsed = true; return(ret); } } Pack r = new Pack(); r.AddStr("SvcName", Options.SvcName); r.AddStr("Pcid", pcid); r.AddSInt("Ver", CoresConfig.WtcConfig.PseudoVer); r.AddSInt("Build", CoresConfig.WtcConfig.PseudoBuild); r.AddInt("ClientOptions", (uint)clientOptions.Flags); r.AddData("ClientId", Options.ClientId); var p = await WtWpcCall("ClientConnect", r, cancel); p.ThrowIfError(); WtConnectParam c = new WtConnectParam { HostName = p["Hostname"].StrValueNonNullCheck, HostNameForProxy = p["HostNameForProxy"].StrValueNonNullCheck, Port = p["Port"].SIntValue, SessionId = p["SessionId"].DataValueNonNull.ToArray(), ServerMask64 = p["ServerMask64"].Int64Value, WebSocketWildCardDomainName = p["WebSocketWildCardDomainName"].StrValueNonNull, ClientOptions = clientOptions._CloneDeep(), IsStandaloneMode = p["IsStandaloneMode"].BoolValue, }; if (c.WebSocketWildCardDomainName._IsEmpty()) { throw new CoresLibException("c.WebSocketWildCardDomainName is empty."); } if (c.HostName._IsSamei("<<!!samehost!!>>")) { string hostTmp = p["__remote_hostname"].StrValueNonNull; int portTmp = p["__remote_port"].SIntValue; if (hostTmp._IsFilled() && portTmp != 0) { c.HostName = hostTmp; c.Port = portTmp; } } c.CacheUsed = false; if (noCache == false) { WideTunnel.ConnectParamCache[pcid] = c._CloneDeep(); } return(c); }
public WtcOptions(WideTunnel wt, WtConnectParam param) { this.WideTunnel = wt; this.ConnectParam = param; }