mscorlib(4.0.0.0) API with additions
ServicePoint.cs
1 using System.Collections;
3 using System.Diagnostics;
5 using System.IO;
6 using System.Net.Security;
7 using System.Net.Sockets;
11 
12 namespace System.Net
13 {
15  [FriendAccessAllowed]
16  public class ServicePoint
17  {
18  private class HandshakeDoneProcedure
19  {
20  private TlsStream m_SecureStream;
21 
22  private object m_Request;
23 
24  private ServicePoint m_ServicePoint;
25 
26  internal static RemoteCertValidationCallback CreateAdapter(ServicePoint serviePoint, TlsStream secureStream, object request)
27  {
28  HandshakeDoneProcedure @object = new HandshakeDoneProcedure(serviePoint, secureStream, request);
29  return @object.CertValidationCallback;
30  }
31 
32  private HandshakeDoneProcedure(ServicePoint serviePoint, TlsStream secureStream, object request)
33  {
34  m_ServicePoint = serviePoint;
35  m_SecureStream = secureStream;
36  m_Request = request;
37  }
38 
39  private bool CertValidationCallback(string hostName, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
40  {
41  m_ServicePoint.UpdateServerCertificate(certificate);
42  m_ServicePoint.UpdateClientCertificate(m_SecureStream.ClientCertificate);
43  bool flag = true;
44  HttpWebRequest httpWebRequest = m_Request as HttpWebRequest;
45  if (httpWebRequest != null && httpWebRequest.ServerCertValidationCallback != null)
46  {
47  return httpWebRequest.ServerCertValidationCallback.Invoke(m_Request, certificate, chain, sslPolicyErrors);
48  }
49  if (ServicePointManager.GetLegacyCertificatePolicy() != null && m_Request is WebRequest)
50  {
51  flag = false;
52  bool flag2 = ServicePointManager.CertPolicyValidationCallback.Invoke(hostName, m_ServicePoint, certificate, (WebRequest)m_Request, chain, sslPolicyErrors);
53  if (!flag2 && (!ServicePointManager.CertPolicyValidationCallback.UsesDefault || ServicePointManager.ServerCertificateValidationCallback == null))
54  {
55  return flag2;
56  }
57  }
59  {
60  flag = false;
61  return ServicePointManager.ServerCertValidationCallback.Invoke(m_Request, certificate, chain, sslPolicyErrors);
62  }
63  if (flag)
64  {
65  return sslPolicyErrors == SslPolicyErrors.None;
66  }
67  return true;
68  }
69  }
70 
71  private class ConnectSocketState
72  {
73  internal ServicePoint servicePoint;
74 
75  internal Socket s4;
76 
77  internal Socket s6;
78 
79  internal object owner;
80 
81  internal IPAddress[] addresses;
82 
83  internal int currentIndex;
84 
85  internal int i;
86 
87  internal int unsuccessfulAttempts;
88 
89  internal bool connectFailure;
90 
91  internal PooledStream pooledStream;
92 
93  internal ConnectSocketState(ServicePoint servicePoint, PooledStream pooledStream, object owner, Socket s4, Socket s6)
94  {
95  this.servicePoint = servicePoint;
96  this.pooledStream = pooledStream;
97  this.owner = owner;
98  this.s4 = s4;
99  this.s6 = s6;
100  }
101  }
102 
103  internal const int LoopbackConnectionLimit = int.MaxValue;
104 
105  private int m_ConnectionLeaseTimeout;
106 
107  private TimerThread.Queue m_ConnectionLeaseTimerQueue;
108 
109  private bool m_ProxyServicePoint;
110 
111  private bool m_UserChangedLimit;
112 
113  private bool m_UseNagleAlgorithm;
114 
115  private TriState m_HostLoopbackGuess;
116 
117  private int m_ReceiveBufferSize;
118 
119  private bool m_Expect100Continue;
120 
121  private bool m_Understands100Continue;
122 
123  private HttpBehaviour m_HttpBehaviour;
124 
125  private string m_LookupString;
126 
127  private int m_ConnectionLimit;
128 
129  private Hashtable m_ConnectionGroupList;
130 
131  private Uri m_Address;
132 
133  private string m_Host;
134 
135  private int m_Port;
136 
137  private TimerThread.Queue m_IdlingQueue;
138 
139  private TimerThread.Timer m_ExpiringTimer;
140 
141  private DateTime m_IdleSince;
142 
143  private string m_ConnectionName;
144 
145  private int m_CurrentConnections;
146 
147  private bool m_HostMode;
148 
149  private BindIPEndPoint m_BindIPEndPointDelegate;
150 
151  private object m_CachedChannelBinding;
152 
153  private static readonly AsyncCallback m_ConnectCallbackDelegate = ConnectSocketCallback;
154 
155  private readonly TimerThread.Callback m_IdleConnectionGroupTimeoutDelegate;
156 
157  private object m_ServerCertificateOrBytes;
158 
159  private object m_ClientCertificateOrBytes;
160 
161  private bool m_UseTcpKeepAlive;
162 
163  private int m_TcpKeepAliveTime;
164 
165  private int m_TcpKeepAliveInterval;
166 
167  private string m_HostName = string.Empty;
168 
169  private bool m_IsTrustedHost = true;
170 
171  private IPAddress[] m_IPAddressInfoList;
172 
173  private int m_CurrentAddressInfoIndex;
174 
175  private bool m_ConnectedSinceDns;
176 
177  private bool m_AddressListFailed;
178 
179  private DateTime m_LastDnsResolve;
180 
181  private bool m_IPAddressesAreLoopback;
182 
183  internal string LookupString => m_LookupString;
184 
185  internal string Hostname => m_HostName;
186 
187  internal bool IsTrustedHost => m_IsTrustedHost;
188 
192  {
193  get
194  {
195  return m_BindIPEndPointDelegate;
196  }
197  set
198  {
199  ExceptionHelper.InfrastructurePermission.Demand();
200  m_BindIPEndPointDelegate = value;
201  }
202  }
203 
204  internal object CachedChannelBinding => m_CachedChannelBinding;
205 
209  public int ConnectionLeaseTimeout
210  {
211  get
212  {
213  return m_ConnectionLeaseTimeout;
214  }
215  set
216  {
217  if (!ValidationHelper.ValidateRange(value, -1, int.MaxValue))
218  {
219  throw new ArgumentOutOfRangeException("value");
220  }
221  if (value != m_ConnectionLeaseTimeout)
222  {
223  m_ConnectionLeaseTimeout = value;
224  m_ConnectionLeaseTimerQueue = null;
225  }
226  }
227  }
228 
229  internal TimerThread.Queue ConnectionLeaseTimerQueue
230  {
231  get
232  {
233  TimerThread.Queue connectionLeaseTimerQueue = m_ConnectionLeaseTimerQueue;
234  if (connectionLeaseTimerQueue == null)
235  {
236  connectionLeaseTimerQueue = (m_ConnectionLeaseTimerQueue = TimerThread.GetOrCreateQueue(ConnectionLeaseTimeout));
237  }
238  return m_ConnectionLeaseTimerQueue;
239  }
240  }
241 
245  public Uri Address
246  {
247  get
248  {
249  if (m_HostMode)
250  {
251  throw new NotSupportedException(SR.GetString("net_servicePointAddressNotSupportedInHostMode"));
252  }
253  if (m_ProxyServicePoint)
254  {
255  ExceptionHelper.WebPermissionUnrestricted.Demand();
256  }
257  return m_Address;
258  }
259  }
260 
261  internal Uri InternalAddress => m_Address;
262 
263  internal string Host
264  {
265  get
266  {
267  if (m_HostMode)
268  {
269  return m_Host;
270  }
271  return m_Address.Host;
272  }
273  }
274 
275  internal int Port => m_Port;
276 
281  public int MaxIdleTime
282  {
283  get
284  {
285  return m_IdlingQueue.Duration;
286  }
287  set
288  {
289  if (!ValidationHelper.ValidateRange(value, -1, int.MaxValue))
290  {
291  throw new ArgumentOutOfRangeException("value");
292  }
293  if (value != m_IdlingQueue.Duration)
294  {
295  lock (this)
296  {
297  if (m_ExpiringTimer == null || m_ExpiringTimer.Cancel())
298  {
299  m_IdlingQueue = TimerThread.GetOrCreateQueue(value);
300  if (m_ExpiringTimer != null)
301  {
302  double totalMilliseconds = (DateTime.Now - m_IdleSince).TotalMilliseconds;
303  int num = (totalMilliseconds >= 2147483647.0) ? int.MaxValue : ((int)totalMilliseconds);
304  int durationMilliseconds = (value == -1) ? (-1) : ((num < value) ? (value - num) : 0);
305  m_ExpiringTimer = TimerThread.CreateQueue(durationMilliseconds).CreateTimer(ServicePointManager.IdleServicePointTimeoutDelegate, this);
306  }
307  }
308  }
309  }
310  }
311  }
312 
316  public bool UseNagleAlgorithm
317  {
318  get
319  {
320  return m_UseNagleAlgorithm;
321  }
322  set
323  {
324  m_UseNagleAlgorithm = value;
325  }
326  }
327 
331  public int ReceiveBufferSize
332  {
333  get
334  {
335  return m_ReceiveBufferSize;
336  }
337  set
338  {
339  if (!ValidationHelper.ValidateRange(value, -1, int.MaxValue))
340  {
341  throw new ArgumentOutOfRangeException("value");
342  }
343  m_ReceiveBufferSize = value;
344  }
345  }
346 
350  public bool Expect100Continue
351  {
352  get
353  {
354  return m_Expect100Continue;
355  }
356  set
357  {
358  m_Expect100Continue = value;
359  }
360  }
361 
364  public DateTime IdleSince => m_IdleSince;
365 
368  public virtual Version ProtocolVersion
369  {
370  get
371  {
372  if ((int)m_HttpBehaviour <= 1 && m_HttpBehaviour != 0)
373  {
374  return HttpVersion.Version10;
375  }
376  return HttpVersion.Version11;
377  }
378  }
379 
380  internal HttpBehaviour HttpBehaviour
381  {
382  get
383  {
384  return m_HttpBehaviour;
385  }
386  set
387  {
388  m_HttpBehaviour = value;
389  m_Understands100Continue = (m_Understands100Continue && ((int)m_HttpBehaviour > 1 || m_HttpBehaviour == HttpBehaviour.Unknown));
390  }
391  }
392 
395  public string ConnectionName => m_ConnectionName;
396 
400  public int ConnectionLimit
401  {
402  get
403  {
404  if (!m_UserChangedLimit && m_IPAddressInfoList == null && m_HostLoopbackGuess == TriState.Unspecified)
405  {
406  lock (this)
407  {
408  if (!m_UserChangedLimit && m_IPAddressInfoList == null && m_HostLoopbackGuess == TriState.Unspecified)
409  {
410  IPAddress address = null;
411  if (IPAddress.TryParse(m_Host, out address))
412  {
413  m_HostLoopbackGuess = (IsAddressListLoopback(new IPAddress[1]
414  {
415  address
416  }) ? TriState.True : TriState.False);
417  }
418  else
419  {
420  m_HostLoopbackGuess = (NclUtilities.GuessWhetherHostIsLoopback(m_Host) ? TriState.True : TriState.False);
421  }
422  }
423  }
424  }
425  if (!m_UserChangedLimit && !((m_IPAddressInfoList == null) ? (m_HostLoopbackGuess != TriState.True) : (!m_IPAddressesAreLoopback)))
426  {
427  return int.MaxValue;
428  }
429  return m_ConnectionLimit;
430  }
431  set
432  {
433  if (value <= 0)
434  {
435  throw new ArgumentOutOfRangeException("value");
436  }
437  if (!m_UserChangedLimit || m_ConnectionLimit != value)
438  {
439  lock (this)
440  {
441  if (!m_UserChangedLimit || m_ConnectionLimit != value)
442  {
443  m_ConnectionLimit = value;
444  m_UserChangedLimit = true;
445  ResolveConnectionLimit();
446  }
447  }
448  }
449  }
450  }
451 
454  public int CurrentConnections
455  {
456  get
457  {
458  int num = 0;
459  lock (this)
460  {
461  foreach (ConnectionGroup value in m_ConnectionGroupList.Values)
462  {
463  num += value.CurrentConnections;
464  }
465  return num;
466  }
467  }
468  }
469 
473  {
474  get
475  {
476  object serverCertificateOrBytes = m_ServerCertificateOrBytes;
477  if (serverCertificateOrBytes != null && serverCertificateOrBytes.GetType() == typeof(byte[]))
478  {
479  return (X509Certificate)(m_ServerCertificateOrBytes = new X509Certificate((byte[])serverCertificateOrBytes));
480  }
481  return serverCertificateOrBytes as X509Certificate;
482  }
483  }
484 
488  {
489  get
490  {
491  object clientCertificateOrBytes = m_ClientCertificateOrBytes;
492  if (clientCertificateOrBytes != null && clientCertificateOrBytes.GetType() == typeof(byte[]))
493  {
494  return (X509Certificate)(m_ClientCertificateOrBytes = new X509Certificate((byte[])clientCertificateOrBytes));
495  }
496  return clientCertificateOrBytes as X509Certificate;
497  }
498  }
499 
503  public bool SupportsPipelining
504  {
505  get
506  {
507  if ((int)m_HttpBehaviour <= 1)
508  {
509  return m_HttpBehaviour == HttpBehaviour.Unknown;
510  }
511  return true;
512  }
513  }
514 
515  internal bool Understands100Continue
516  {
517  get
518  {
519  return m_Understands100Continue;
520  }
521  set
522  {
523  m_Understands100Continue = value;
524  }
525  }
526 
527  internal bool InternalProxyServicePoint => m_ProxyServicePoint;
528 
529  private bool HasTimedOut
530  {
531  get
532  {
533  int dnsRefreshTimeout = ServicePointManager.DnsRefreshTimeout;
534  if (dnsRefreshTimeout != -1)
535  {
536  return m_LastDnsResolve + new TimeSpan(0, 0, 0, 0, dnsRefreshTimeout) < DateTime.UtcNow;
537  }
538  return false;
539  }
540  }
541 
542  internal ServicePoint(Uri address, TimerThread.Queue defaultIdlingQueue, int defaultConnectionLimit, string lookupString, bool userChangedLimit, bool proxyServicePoint)
543  {
544  if (Logging.On)
545  {
546  Logging.Enter(Logging.Web, this, "ServicePoint", address.DnsSafeHost + ":" + address.Port);
547  }
548  m_ProxyServicePoint = proxyServicePoint;
549  m_Address = address;
550  m_ConnectionName = address.Scheme;
551  m_Host = address.DnsSafeHost;
552  m_Port = address.Port;
553  m_IdlingQueue = defaultIdlingQueue;
554  m_ConnectionLimit = defaultConnectionLimit;
555  m_HostLoopbackGuess = TriState.Unspecified;
556  m_LookupString = lookupString;
557  m_UserChangedLimit = userChangedLimit;
558  m_UseNagleAlgorithm = ServicePointManager.UseNagleAlgorithm;
559  m_Expect100Continue = ServicePointManager.Expect100Continue;
560  m_ConnectionGroupList = new Hashtable(10);
561  m_ConnectionLeaseTimeout = -1;
562  m_ReceiveBufferSize = -1;
563  m_UseTcpKeepAlive = ServicePointManager.s_UseTcpKeepAlive;
564  m_TcpKeepAliveTime = ServicePointManager.s_TcpKeepAliveTime;
565  m_TcpKeepAliveInterval = ServicePointManager.s_TcpKeepAliveInterval;
566  m_Understands100Continue = true;
567  m_HttpBehaviour = HttpBehaviour.Unknown;
568  m_IdleSince = DateTime.Now;
569  m_ExpiringTimer = m_IdlingQueue.CreateTimer(ServicePointManager.IdleServicePointTimeoutDelegate, this);
570  m_IdleConnectionGroupTimeoutDelegate = IdleConnectionGroupTimeoutCallback;
571  }
572 
573  internal ServicePoint(string host, int port, TimerThread.Queue defaultIdlingQueue, int defaultConnectionLimit, string lookupString, bool userChangedLimit, bool proxyServicePoint)
574  {
575  if (Logging.On)
576  {
577  Logging.Enter(Logging.Web, this, "ServicePoint", host + ":" + port);
578  }
579  m_ProxyServicePoint = proxyServicePoint;
580  m_ConnectionName = "ByHost:" + host + ":" + port.ToString(CultureInfo.InvariantCulture);
581  m_IdlingQueue = defaultIdlingQueue;
582  m_ConnectionLimit = defaultConnectionLimit;
583  m_HostLoopbackGuess = TriState.Unspecified;
584  m_LookupString = lookupString;
585  m_UserChangedLimit = userChangedLimit;
586  m_ConnectionGroupList = new Hashtable(10);
587  m_ConnectionLeaseTimeout = -1;
588  m_ReceiveBufferSize = -1;
589  m_Host = host;
590  m_Port = port;
591  m_HostMode = true;
592  m_IdleSince = DateTime.Now;
593  m_ExpiringTimer = m_IdlingQueue.CreateTimer(ServicePointManager.IdleServicePointTimeoutDelegate, this);
594  m_IdleConnectionGroupTimeoutDelegate = IdleConnectionGroupTimeoutCallback;
595  }
596 
597  internal void SetCachedChannelBinding(Uri uri, ChannelBinding binding)
598  {
599  if (uri.Scheme == Uri.UriSchemeHttps)
600  {
601  m_CachedChannelBinding = ((binding != null) ? ((object)binding) : ((object)DBNull.Value));
602  }
603  }
604 
605  private ConnectionGroup FindConnectionGroup(string connName, bool dontCreate)
606  {
607  string key = ConnectionGroup.MakeQueryStr(connName);
608  ConnectionGroup connectionGroup = m_ConnectionGroupList[key] as ConnectionGroup;
609  if (connectionGroup == null && !dontCreate)
610  {
611  connectionGroup = new ConnectionGroup(this, connName);
612  m_ConnectionGroupList[key] = connectionGroup;
613  }
614  return connectionGroup;
615  }
616 
617  internal Socket GetConnection(PooledStream PooledStream, object owner, bool async, out IPAddress address, ref Socket abortSocket, ref Socket abortSocket6)
618  {
619  Socket socket = null;
620  Socket socket2 = null;
621  Socket socket3 = null;
622  Exception exception = null;
623  WebExceptionStatus webExceptionStatus = WebExceptionStatus.ConnectFailure;
624  address = null;
626  {
627  socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
628  }
630  {
631  socket2 = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
632  }
633  abortSocket = socket;
634  abortSocket6 = socket2;
635  ConnectSocketState state = null;
636  if (async)
637  {
638  state = new ConnectSocketState(this, PooledStream, owner, socket, socket2);
639  }
640  webExceptionStatus = ConnectSocket(socket, socket2, ref socket3, ref address, state, out exception);
641  switch (webExceptionStatus)
642  {
643  case WebExceptionStatus.Pending:
644  return null;
645  default:
646  throw new WebException(NetRes.GetWebStatusString(webExceptionStatus), (webExceptionStatus == WebExceptionStatus.ProxyNameResolutionFailure || webExceptionStatus == WebExceptionStatus.NameResolutionFailure) ? Host : null, exception, webExceptionStatus, null, WebExceptionInternalStatus.ServicePointFatal);
647  case WebExceptionStatus.Success:
648  if (socket3 == null)
649  {
650  throw new IOException(SR.GetString("net_io_transportfailure"));
651  }
652  CompleteGetConnection(socket, socket2, socket3, address);
653  return socket3;
654  }
655  }
656 
657  private void CompleteGetConnection(Socket socket, Socket socket6, Socket finalSocket, IPAddress address)
658  {
659  if (finalSocket.AddressFamily == AddressFamily.InterNetwork)
660  {
661  if (socket6 != null)
662  {
663  socket6.Close();
664  socket6 = null;
665  }
666  }
667  else if (socket != null)
668  {
669  socket.Close();
670  socket = null;
671  }
672  if (!UseNagleAlgorithm)
673  {
674  finalSocket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.Debug, 1);
675  }
676  if (ReceiveBufferSize != -1)
677  {
678  finalSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, ReceiveBufferSize);
679  }
680  if (m_UseTcpKeepAlive)
681  {
682  finalSocket.IOControl(IOControlCode.KeepAliveValues, new byte[12]
683  {
684  1,
685  0,
686  0,
687  0,
688  (byte)(m_TcpKeepAliveTime & 0xFF),
689  (byte)((m_TcpKeepAliveTime >> 8) & 0xFF),
690  (byte)((m_TcpKeepAliveTime >> 16) & 0xFF),
691  (byte)((m_TcpKeepAliveTime >> 24) & 0xFF),
692  (byte)(m_TcpKeepAliveInterval & 0xFF),
693  (byte)((m_TcpKeepAliveInterval >> 8) & 0xFF),
694  (byte)((m_TcpKeepAliveInterval >> 16) & 0xFF),
695  (byte)((m_TcpKeepAliveInterval >> 24) & 0xFF)
696  }, null);
697  }
698  }
699 
700  internal virtual void SubmitRequest(HttpWebRequest request)
701  {
702  SubmitRequest(request, null);
703  }
704 
705  internal void SubmitRequest(HttpWebRequest request, string connName)
706  {
707  bool forcedsubmit = false;
708  ConnectionGroup connectionGroup;
709  lock (this)
710  {
711  connectionGroup = FindConnectionGroup(connName, dontCreate: false);
712  }
713  Connection connection;
714  do
715  {
716  connection = connectionGroup.FindConnection(request, connName, out forcedsubmit);
717  }
718  while (connection != null && !connection.SubmitRequest(request, forcedsubmit));
719  }
720 
724  public bool CloseConnectionGroup(string connectionGroupName)
725  {
726  if (ReleaseConnectionGroup(HttpWebRequest.GenerateConnectionGroup(connectionGroupName, unsafeConnectionGroup: false, isInternalGroup: false).ToString()) || ReleaseConnectionGroup(HttpWebRequest.GenerateConnectionGroup(connectionGroupName, unsafeConnectionGroup: true, isInternalGroup: false).ToString()) || ConnectionPoolManager.RemoveConnectionPool(this, connectionGroupName))
727  {
728  return true;
729  }
730  return false;
731  }
732 
733  internal void CloseConnectionGroupInternal(string connectionGroupName)
734  {
735  string value = HttpWebRequest.GenerateConnectionGroup(connectionGroupName, unsafeConnectionGroup: false, isInternalGroup: true).ToString();
736  string value2 = HttpWebRequest.GenerateConnectionGroup(connectionGroupName, unsafeConnectionGroup: true, isInternalGroup: true).ToString();
737  List<string> list = null;
738  lock (this)
739  {
740  foreach (object key in m_ConnectionGroupList.Keys)
741  {
742  string text = key as string;
743  if (text.StartsWith(value, StringComparison.Ordinal) || text.StartsWith(value2, StringComparison.Ordinal))
744  {
745  if (list == null)
746  {
747  list = new List<string>();
748  }
749  list.Add(text);
750  }
751  }
752  }
753  if (list != null)
754  {
755  foreach (string item in list)
756  {
757  ReleaseConnectionGroup(item);
758  }
759  }
760  }
761 
762  private void ResolveConnectionLimit()
763  {
764  int connectionLimit = ConnectionLimit;
765  foreach (ConnectionGroup value in m_ConnectionGroupList.Values)
766  {
767  value.ConnectionLimit = connectionLimit;
768  }
769  }
770 
771  internal void UpdateServerCertificate(X509Certificate certificate)
772  {
773  if (certificate != null)
774  {
775  m_ServerCertificateOrBytes = certificate.GetRawCertData();
776  }
777  else
778  {
779  m_ServerCertificateOrBytes = null;
780  }
781  }
782 
783  internal void UpdateClientCertificate(X509Certificate certificate)
784  {
785  if (certificate != null)
786  {
787  m_ClientCertificateOrBytes = certificate.GetRawCertData();
788  }
789  else
790  {
791  m_ClientCertificateOrBytes = null;
792  }
793  }
794 
800  public void SetTcpKeepAlive(bool enabled, int keepAliveTime, int keepAliveInterval)
801  {
802  if (enabled)
803  {
804  m_UseTcpKeepAlive = true;
805  if (keepAliveTime <= 0)
806  {
807  throw new ArgumentOutOfRangeException("keepAliveTime");
808  }
809  if (keepAliveInterval <= 0)
810  {
811  throw new ArgumentOutOfRangeException("keepAliveInterval");
812  }
813  m_TcpKeepAliveTime = keepAliveTime;
814  m_TcpKeepAliveInterval = keepAliveInterval;
815  }
816  else
817  {
818  m_UseTcpKeepAlive = false;
819  m_TcpKeepAliveTime = 0;
820  m_TcpKeepAliveInterval = 0;
821  }
822  }
823 
824  internal void IncrementConnection()
825  {
826  lock (this)
827  {
828  m_CurrentConnections++;
829  if (m_CurrentConnections == 1)
830  {
831  m_ExpiringTimer.Cancel();
832  m_ExpiringTimer = null;
833  }
834  }
835  }
836 
837  internal void DecrementConnection()
838  {
839  lock (this)
840  {
841  m_CurrentConnections--;
842  if (m_CurrentConnections == 0)
843  {
844  m_IdleSince = DateTime.Now;
845  m_ExpiringTimer = m_IdlingQueue.CreateTimer(ServicePointManager.IdleServicePointTimeoutDelegate, this);
846  }
847  else if (m_CurrentConnections < 0)
848  {
849  m_CurrentConnections = 0;
850  }
851  }
852  }
853 
854  internal RemoteCertValidationCallback SetupHandshakeDoneProcedure(TlsStream secureStream, object request)
855  {
856  return HandshakeDoneProcedure.CreateAdapter(this, secureStream, request);
857  }
858 
859  private void IdleConnectionGroupTimeoutCallback(TimerThread.Timer timer, int timeNoticed, object context)
860  {
861  ConnectionGroup connectionGroup = (ConnectionGroup)context;
862  if (Logging.On)
863  {
864  Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_closed_idle", "ConnectionGroup", connectionGroup.GetHashCode()));
865  }
866  ReleaseConnectionGroup(connectionGroup.Name);
867  }
868 
869  internal TimerThread.Timer CreateConnectionGroupTimer(ConnectionGroup connectionGroup)
870  {
871  return m_IdlingQueue.CreateTimer(m_IdleConnectionGroupTimeoutDelegate, connectionGroup);
872  }
873 
874  internal bool ReleaseConnectionGroup(string connName)
875  {
876  ConnectionGroup connectionGroup = null;
877  lock (this)
878  {
879  connectionGroup = FindConnectionGroup(connName, dontCreate: true);
880  if (connectionGroup == null)
881  {
882  return false;
883  }
884  connectionGroup.CancelIdleTimer();
885  m_ConnectionGroupList.Remove(connName);
886  }
887  connectionGroup.DisableKeepAliveOnConnections();
888  return true;
889  }
890 
891  internal void ReleaseAllConnectionGroups()
892  {
893  ArrayList arrayList = new ArrayList(m_ConnectionGroupList.Count);
894  lock (this)
895  {
896  foreach (ConnectionGroup value in m_ConnectionGroupList.Values)
897  {
898  arrayList.Add(value);
899  }
900  m_ConnectionGroupList.Clear();
901  }
902  foreach (ConnectionGroup item in arrayList)
903  {
904  item.DisableKeepAliveOnConnections();
905  }
906  }
907 
908  private static void ConnectSocketCallback(IAsyncResult asyncResult)
909  {
910  ConnectSocketState connectSocketState = (ConnectSocketState)asyncResult.AsyncState;
911  Socket socket = null;
912  IPAddress address = null;
913  Exception exception = null;
914  Exception e = null;
915  WebExceptionStatus webExceptionStatus = WebExceptionStatus.ConnectFailure;
916  try
917  {
918  webExceptionStatus = connectSocketState.servicePoint.ConnectSocketInternal(connectSocketState.connectFailure, connectSocketState.s4, connectSocketState.s6, ref socket, ref address, connectSocketState, asyncResult, out exception);
919  }
920  catch (SocketException ex)
921  {
922  e = ex;
923  }
924  catch (ObjectDisposedException ex2)
925  {
926  e = ex2;
927  }
928  switch (webExceptionStatus)
929  {
930  case WebExceptionStatus.Pending:
931  return;
932  case WebExceptionStatus.Success:
933  try
934  {
935  connectSocketState.servicePoint.CompleteGetConnection(connectSocketState.s4, connectSocketState.s6, socket, address);
936  }
937  catch (SocketException ex3)
938  {
939  e = ex3;
940  }
941  catch (ObjectDisposedException ex4)
942  {
943  e = ex4;
944  }
945  break;
946  default:
947  e = new WebException(NetRes.GetWebStatusString(webExceptionStatus), (webExceptionStatus == WebExceptionStatus.ProxyNameResolutionFailure || webExceptionStatus == WebExceptionStatus.NameResolutionFailure) ? connectSocketState.servicePoint.Host : null, exception, webExceptionStatus, null, WebExceptionInternalStatus.ServicePointFatal);
948  break;
949  }
950  try
951  {
952  connectSocketState.pooledStream.ConnectionCallback(connectSocketState.owner, e, socket, address);
953  }
954  catch
955  {
956  if (socket == null || !socket.CleanedUp)
957  {
958  throw;
959  }
960  }
961  }
962 
963  private void BindUsingDelegate(Socket socket, IPEndPoint remoteIPEndPoint)
964  {
965  IPEndPoint remoteEndPoint = new IPEndPoint(remoteIPEndPoint.Address, remoteIPEndPoint.Port);
966  int i;
967  for (i = 0; i < int.MaxValue; i++)
968  {
969  IPEndPoint iPEndPoint = BindIPEndPointDelegate(this, remoteEndPoint, i);
970  if (iPEndPoint != null)
971  {
972  try
973  {
974  socket.InternalBind(iPEndPoint);
975  }
976  catch
977  {
978  continue;
979  }
980  }
981  break;
982  }
983  if (i == int.MaxValue)
984  {
985  throw new OverflowException("Reached maximum number of BindIPEndPointDelegate retries");
986  }
987  }
988 
989  private void SetUnicastReusePortForSocket(Socket socket)
990  {
991  if ((!ServicePointManager.ReusePortSupported.HasValue || ServicePointManager.ReusePortSupported.Value) && ServicePointManager.ReusePort)
992  {
993  try
994  {
995  socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseUnicastPort, 1);
996  if (Logging.On)
997  {
998  Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_set_socketoption_reuseport", "Socket", socket.GetHashCode()));
999  }
1000  ServicePointManager.ReusePortSupported = true;
1001  }
1002  catch (SocketException)
1003  {
1004  if (Logging.On)
1005  {
1006  Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_set_socketoption_reuseport_not_supported", "Socket", socket.GetHashCode()));
1007  }
1008  ServicePointManager.ReusePortSupported = false;
1009  }
1010  catch (Exception ex2)
1011  {
1012  if (Logging.On)
1013  {
1014  Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_unexpected_exception", ex2.Message));
1015  }
1016  }
1017  }
1018  }
1019 
1020  private WebExceptionStatus ConnectSocketInternal(bool connectFailure, Socket s4, Socket s6, ref Socket socket, ref IPAddress address, ConnectSocketState state, IAsyncResult asyncResult, out Exception exception)
1021  {
1022  exception = null;
1023  IPAddress[] array = null;
1024  for (int i = 0; i < 2; i++)
1025  {
1026  int j = 0;
1027  int currentIndex;
1028  if (asyncResult == null)
1029  {
1030  array = GetIPAddressInfoList(out currentIndex, array);
1031  if (array == null || array.Length == 0)
1032  {
1033  break;
1034  }
1035  }
1036  else
1037  {
1038  array = state.addresses;
1039  currentIndex = state.currentIndex;
1040  j = state.i;
1041  i = state.unsuccessfulAttempts;
1042  }
1043  for (; j < array.Length; j++)
1044  {
1045  IPAddress iPAddress = array[currentIndex];
1046  try
1047  {
1048  IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, m_Port);
1049  Socket socket2 = (iPEndPoint.Address.AddressFamily != AddressFamily.InterNetwork) ? s6 : s4;
1050  if (state != null)
1051  {
1052  if (asyncResult == null)
1053  {
1054  state.addresses = array;
1055  state.currentIndex = currentIndex;
1056  state.i = j;
1057  state.unsuccessfulAttempts = i;
1058  state.connectFailure = connectFailure;
1059  if (!socket2.IsBound)
1060  {
1061  if (ServicePointManager.ReusePort)
1062  {
1063  SetUnicastReusePortForSocket(socket2);
1064  }
1065  if (BindIPEndPointDelegate != null)
1066  {
1067  BindUsingDelegate(socket2, iPEndPoint);
1068  }
1069  }
1070  socket2.UnsafeBeginConnect(iPEndPoint, m_ConnectCallbackDelegate, state);
1071  return WebExceptionStatus.Pending;
1072  }
1073  IAsyncResult asyncResult2 = asyncResult;
1074  asyncResult = null;
1075  socket2.EndConnect(asyncResult2);
1076  }
1077  else
1078  {
1079  if (!socket2.IsBound)
1080  {
1081  if (ServicePointManager.ReusePort)
1082  {
1083  SetUnicastReusePortForSocket(socket2);
1084  }
1085  if (BindIPEndPointDelegate != null)
1086  {
1087  BindUsingDelegate(socket2, iPEndPoint);
1088  }
1089  }
1090  socket2.InternalConnect(iPEndPoint);
1091  }
1092  socket = socket2;
1093  address = iPAddress;
1094  exception = null;
1095  UpdateCurrentIndex(array, currentIndex);
1096  return WebExceptionStatus.Success;
1097  }
1098  catch (ObjectDisposedException)
1099  {
1100  return WebExceptionStatus.RequestCanceled;
1101  }
1102  catch (Exception ex2)
1103  {
1104  if (NclUtilities.IsFatal(ex2))
1105  {
1106  throw;
1107  }
1108  exception = ex2;
1109  connectFailure = true;
1110  }
1111  currentIndex++;
1112  if (currentIndex >= array.Length)
1113  {
1114  currentIndex = 0;
1115  }
1116  }
1117  }
1118  Failed(array);
1119  if (!connectFailure)
1120  {
1121  if (!InternalProxyServicePoint)
1122  {
1123  return WebExceptionStatus.NameResolutionFailure;
1124  }
1125  return WebExceptionStatus.ProxyNameResolutionFailure;
1126  }
1127  return WebExceptionStatus.ConnectFailure;
1128  }
1129 
1130  private WebExceptionStatus ConnectSocket(Socket s4, Socket s6, ref Socket socket, ref IPAddress address, ConnectSocketState state, out Exception exception)
1131  {
1132  return ConnectSocketInternal(connectFailure: false, s4, s6, ref socket, ref address, state, null, out exception);
1133  }
1134 
1135  [Conditional("DEBUG")]
1136  internal void DebugMembers(int requestHash)
1137  {
1138  foreach (ConnectionGroup value in m_ConnectionGroupList.Values)
1139  {
1140  if (value != null)
1141  {
1142  try
1143  {
1144  }
1145  catch
1146  {
1147  }
1148  }
1149  }
1150  }
1151 
1152  private void Failed(IPAddress[] addresses)
1153  {
1154  if (addresses == m_IPAddressInfoList)
1155  {
1156  lock (this)
1157  {
1158  if (addresses == m_IPAddressInfoList)
1159  {
1160  m_AddressListFailed = true;
1161  }
1162  }
1163  }
1164  }
1165 
1166  private void UpdateCurrentIndex(IPAddress[] addresses, int currentIndex)
1167  {
1168  if (addresses == m_IPAddressInfoList && (m_CurrentAddressInfoIndex != currentIndex || !m_ConnectedSinceDns))
1169  {
1170  lock (this)
1171  {
1172  if (addresses == m_IPAddressInfoList)
1173  {
1174  if (!ServicePointManager.EnableDnsRoundRobin)
1175  {
1176  m_CurrentAddressInfoIndex = currentIndex;
1177  }
1178  m_ConnectedSinceDns = true;
1179  }
1180  }
1181  }
1182  }
1183 
1184  private IPAddress[] GetIPAddressInfoList(out int currentIndex, IPAddress[] addresses)
1185  {
1186  IPHostEntry result = null;
1187  currentIndex = 0;
1188  bool flag = false;
1189  bool flag2 = false;
1190  lock (this)
1191  {
1192  if (addresses != null && !m_ConnectedSinceDns && !m_AddressListFailed && addresses == m_IPAddressInfoList)
1193  {
1194  return null;
1195  }
1196  if (m_IPAddressInfoList == null || m_AddressListFailed || addresses == m_IPAddressInfoList || HasTimedOut)
1197  {
1198  m_CurrentAddressInfoIndex = 0;
1199  m_ConnectedSinceDns = false;
1200  m_AddressListFailed = false;
1201  m_LastDnsResolve = DateTime.UtcNow;
1202  flag = true;
1203  }
1204  }
1205  if (flag)
1206  {
1207  try
1208  {
1209  flag2 = !Dns.TryInternalResolve(m_Host, out result);
1210  }
1211  catch (Exception exception)
1212  {
1213  if (NclUtilities.IsFatal(exception))
1214  {
1215  throw;
1216  }
1217  flag2 = true;
1218  }
1219  }
1220  lock (this)
1221  {
1222  if (flag)
1223  {
1224  m_IPAddressInfoList = null;
1225  if (!flag2 && result != null && result.AddressList != null && result.AddressList.Length != 0)
1226  {
1227  SetAddressList(result);
1228  }
1229  }
1230  if (m_IPAddressInfoList != null && m_IPAddressInfoList.Length != 0)
1231  {
1232  currentIndex = m_CurrentAddressInfoIndex;
1233  if (ServicePointManager.EnableDnsRoundRobin)
1234  {
1235  m_CurrentAddressInfoIndex++;
1236  if (m_CurrentAddressInfoIndex >= m_IPAddressInfoList.Length)
1237  {
1238  m_CurrentAddressInfoIndex = 0;
1239  }
1240  }
1241  return m_IPAddressInfoList;
1242  }
1243  }
1244  return null;
1245  }
1246 
1247  private void SetAddressList(IPHostEntry ipHostEntry)
1248  {
1249  bool iPAddressesAreLoopback = m_IPAddressesAreLoopback;
1250  bool flag = m_IPAddressInfoList == null;
1251  m_IPAddressesAreLoopback = IsAddressListLoopback(ipHostEntry.AddressList);
1252  m_IPAddressInfoList = ipHostEntry.AddressList;
1253  m_HostName = ipHostEntry.HostName;
1254  m_IsTrustedHost = ipHostEntry.isTrustedHost;
1255  if (flag || iPAddressesAreLoopback != m_IPAddressesAreLoopback)
1256  {
1257  ResolveConnectionLimit();
1258  }
1259  }
1260 
1261  private static bool IsAddressListLoopback(IPAddress[] addressList)
1262  {
1263  IPAddress[] array = null;
1264  try
1265  {
1266  array = NclUtilities.LocalAddresses;
1267  }
1268  catch (Exception ex)
1269  {
1270  if (NclUtilities.IsFatal(ex))
1271  {
1272  throw;
1273  }
1274  if (Logging.On)
1275  {
1276  Logging.PrintError(Logging.Web, SR.GetString("net_log_retrieving_localhost_exception", ex));
1277  Logging.PrintWarning(Logging.Web, SR.GetString("net_log_resolved_servicepoint_may_not_be_remote_server"));
1278  }
1279  }
1280  int i;
1281  for (i = 0; i < addressList.Length; i++)
1282  {
1283  if (!IPAddress.IsLoopback(addressList[i]))
1284  {
1285  if (array == null)
1286  {
1287  break;
1288  }
1289  int j;
1290  for (j = 0; j < array.Length && !addressList[i].Equals(array[j]); j++)
1291  {
1292  }
1293  if (j >= array.Length)
1294  {
1295  break;
1296  }
1297  }
1298  }
1299  return i == addressList.Length;
1300  }
1301  }
1302 }
static CultureInfo InvariantCulture
Gets the T:System.Globalization.CultureInfo object that is culture-independent (invariant).
Definition: CultureInfo.cs:263
DateTime IdleSince
Gets the date and time that the T:System.Net.ServicePoint object was last connected to a host.
static RemoteCertificateValidationCallback ServerCertificateValidationCallback
Gets or sets the callback to validate a server certificate.
SslPolicyErrors
Enumerates Secure Socket Layer (SSL) policy errors.
The host name is a domain name system (DNS) style host name.
The T:System.Security.Authentication.ExtendedProtection.ChannelBinding class encapsulates a pointer t...
static readonly Version Version11
Defines a T:System.Version instance for HTTP 1.1.
Definition: HttpVersion.cs:10
SocketOptionName
Defines configuration option names.
void SetTcpKeepAlive(bool enabled, int keepAliveTime, int keepAliveInterval)
Enables or disables the keep-alive option on a TCP connection.
X509Certificate ClientCertificate
Gets the last client certificate sent to the server.
StringComparison
Specifies the culture, case, and sort rules to be used by certain overloads of the M:System....
The notification failed for any reason.
Makes a request to a Uniform Resource Identifier (URI). This is an abstract class.
Definition: WebRequest.cs:21
int IOControl(int ioControlCode, byte[] optionInValue, byte[] optionOutValue)
Sets low-level operating modes for the T:System.Net.Sockets.Socket using numerical control codes.
Definition: Socket.cs:2505
Manages the collection of T:System.Net.ServicePoint objects.
Definition: __Canon.cs:3
string Scheme
Gets the scheme name for this URI.
Definition: Uri.cs:702
The exception that is thrown when the value of an argument is outside the allowable range of values a...
delegate void AsyncCallback(IAsyncResult ar)
References a method to be called when a corresponding asynchronous operation completes.
AddressFamily AddressFamily
Gets the address family of the T:System.Net.Sockets.Socket.
Definition: Socket.cs:473
void EndConnect(IAsyncResult asyncResult)
Ends a pending asynchronous connection request.
Definition: Socket.cs:3423
Implements the Berkeley sockets interface.
Definition: Socket.cs:16
bool SupportsPipelining
Indicates whether the T:System.Net.ServicePoint object supports pipelined connections.
X509Certificate Certificate
Gets the certificate received for this T:System.Net.ServicePoint object.
Represents an instant in time, typically expressed as a date and time of day. To browse the ....
Definition: DateTime.cs:13
Defines the HTTP version numbers that are supported by the T:System.Net.HttpWebRequest and T:System....
Definition: HttpVersion.cs:4
static bool TryParse(string ipString, out IPAddress address)
Determines whether a string is a valid IP address.
Definition: IPAddress.cs:357
int??? ConnectionLimit
Gets or sets the maximum number of connections allowed on this T:System.Net.ServicePoint object.
The exception that is thrown when a socket error occurs.
A type representing a date and time value.
bool UseNagleAlgorithm
Gets or sets a T:System.Boolean value that determines whether the Nagle algorithm is used on connecti...
int??? MaxIdleTime
Gets or sets the amount of time a connection associated with the T:System.Net.ServicePoint object can...
BindIPEndPoint BindIPEndPointDelegate
Specifies the delegate to associate a local T:System.Net.IPEndPoint with a T:System....
void Close()
Closes the T:System.Net.Sockets.Socket connection and releases all associated resources.
Definition: Socket.cs:1323
virtual ICollection Values
Gets an T:System.Collections.ICollection containing the values in the T:System.Collections....
Definition: Hashtable.cs:631
Provides an Internet Protocol (IP) address.
Definition: IPAddress.cs:10
IOControlCode
Specifies the IO control codes supported by the M:System.Net.Sockets.Socket.IOControl(System....
Definition: IOControlCode.cs:4
int ConnectionLeaseTimeout
Gets or sets the number of milliseconds after which an active T:System.Net.ServicePoint connection is...
SocketType
Specifies the type of socket that an instance of the T:System.Net.Sockets.Socket class represents.
Definition: SocketType.cs:4
bool Expect100Continue
Gets or sets a T:System.Boolean value that determines whether 100-Continue behavior is used.
static readonly Version Version10
Defines a T:System.Version instance for HTTP 1.0.
Definition: HttpVersion.cs:7
AddressFamily
Specifies the addressing scheme that an instance of the T:System.Net.Sockets.Socket class can use.
Definition: AddressFamily.cs:5
Represents a collection of key/value pairs that are organized based on the hash code of the key....
Definition: Hashtable.cs:17
virtual ICollection Keys
Gets an T:System.Collections.ICollection containing the keys in the T:System.Collections....
Definition: Hashtable.cs:617
The exception that is thrown when an I/O error occurs.
Definition: IOException.cs:10
SocketOptionLevel
Defines socket option levels for the M:System.Net.Sockets.Socket.SetSocketOption(System....
A database null (column) value.
Uri Address
Gets the Uniform Resource Identifier (URI) of the server that this T:System.Net.ServicePoint object c...
int ReceiveBufferSize
Gets or sets the size of the receiving buffer for the socket used by this T:System....
Represents the version number of an assembly, operating system, or the common language runtime....
Definition: Version.cs:11
Represents a chain-building engine for T:System.Security.Cryptography.X509Certificates....
Definition: X509Chain.cs:10
virtual int Add(object value)
Adds an object to the end of the T:System.Collections.ArrayList.
Definition: ArrayList.cs:2381
WebExceptionStatus
Defines status codes for the T:System.Net.WebException class.
int CurrentConnections
Gets the number of open connections associated with this T:System.Net.ServicePoint object.
virtual Version ProtocolVersion
Gets the version of the HTTP protocol that the T:System.Net.ServicePoint object uses.
virtual byte [] GetRawCertData()
Returns the raw data for the entire X.509v3 certificate as an array of bytes.
virtual void Remove(object key)
Removes the element with the specified key from the T:System.Collections.Hashtable.
Definition: Hashtable.cs:1349
bool CloseConnectionGroup(string connectionGroupName)
Removes the specified connection group from this T:System.Net.ServicePoint object.
static DateTime Now
Gets a T:System.DateTime object that is set to the current date and time on this computer,...
Definition: DateTime.cs:264
Queue()
Initializes a new instance of the T:System.Collections.Queue class that is empty, has the default ini...
Definition: Queue.cs:272
static bool OSSupportsIPv6
Indicates whether the underlying operating system and network adaptors support Internet Protocol vers...
Definition: Socket.cs:268
virtual void Clear()
Removes all elements from the T:System.Collections.Hashtable.
Definition: Hashtable.cs:924
Provides information about a specific culture (called a locale for unmanaged code development)....
Definition: CultureInfo.cs:16
The exception that is thrown when an invoked method is not supported, or when there is an attempt to ...
delegate IPEndPoint BindIPEndPoint(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount)
Represents the method that specifies a local Internet Protocol address and port number for a T:System...
bool IsBound
Gets a value that indicates whether the T:System.Net.Sockets.Socket is bound to a specific local port...
Definition: Socket.cs:486
A conditional operation, such as a > b ? a : b in C# or If(a > b, a, b) in Visual Basic.
Provides an object representation of a uniform resource identifier (URI) and easy access to the parts...
Definition: Uri.cs:19
Provides an HTTP-specific implementation of the T:System.Net.WebRequest class.
string ConnectionName
Gets the connection name.
string Host
Gets the host component of this instance.
Definition: Uri.cs:587
Provides methods that help you use X.509 v.3 certificates.
Provides connection management for HTTP connections.
Definition: ServicePoint.cs:16
virtual int Count
Gets the number of key/value pairs contained in the T:System.Collections.Hashtable.
Definition: Hashtable.cs:658
ProtocolType
Specifies the protocols that the T:System.Net.Sockets.Socket class supports.
Definition: ProtocolType.cs:4
void SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, int optionValue)
Sets the specified T:System.Net.Sockets.Socket option to the specified integer value.
Definition: Socket.cs:2598
Implements the T:System.Collections.IList interface using an array whose size is dynamically increase...
Definition: ArrayList.cs:14
static bool OSSupportsIPv4
Indicates whether the underlying operating system and network adaptors support Internet Protocol vers...
Definition: Socket.cs:234