PageRenderTime 89ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/Framework/Tools/Emulator/Sockets.cs

https://bitbucket.org/CW2/netduinofirmware
C# | 1555 lines | 1209 code | 326 blank | 20 comment | 160 complexity | 9a066437ee7a803dc6c21aaba3b46eca MD5 | raw file
Possible License(s): Apache-2.0
  1. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4. using System;
  5. using System.IO;
  6. using System.Diagnostics;
  7. using System.Runtime.InteropServices;
  8. using System.Collections;
  9. using System.Collections.Generic;
  10. using System.ComponentModel;
  11. using System.Threading;
  12. using System.Net;
  13. using System.Net.Sockets;
  14. using System.Net.NetworkInformation;
  15. using System.Runtime.CompilerServices;
  16. using Microsoft.Win32.SafeHandles;
  17. using Microsoft.SPOT.Emulator.Com;
  18. namespace Microsoft.SPOT.Emulator.Sockets
  19. {
  20. internal class SocketsDriver : HalDriver<ISocketsDriver>, ISocketsDriver
  21. {
  22. internal static class TinyCLRSockets
  23. {
  24. [StructLayout(LayoutKind.Sequential)]
  25. internal class fd_set
  26. {
  27. internal uint count;
  28. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
  29. internal int[] fd_array;
  30. }
  31. }
  32. [StructLayout(LayoutKind.Sequential)]
  33. internal class SockAddr
  34. {
  35. public short sin_family;
  36. public ushort sin_port;
  37. public uint sin_addr;
  38. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
  39. public byte[] sin_zero = new byte[8];
  40. public void MarshalFromNative(IntPtr native)
  41. {
  42. Marshal.PtrToStructure(native, this);
  43. sin_port = (ushort)(((sin_port & 0xFF) << 8) | ((sin_port >> 8) & 0xFF));
  44. }
  45. public void MarshalToNative(IntPtr native)
  46. {
  47. sin_port = (ushort)(((sin_port & 0xFF) << 8) | ((sin_port >> 8) & 0xFF));
  48. Marshal.StructureToPtr(this, native, true);
  49. }
  50. }
  51. internal static class NativeSockets
  52. {
  53. [StructLayout(LayoutKind.Sequential)]
  54. internal class fd_set
  55. {
  56. const int FD_SETSIZE = 64;
  57. internal uint count;
  58. [MarshalAs(UnmanagedType.ByValArray, SizeConst = FD_SETSIZE)]
  59. internal IntPtr[] fd_array;
  60. public fd_set()
  61. {
  62. fd_array = new IntPtr[FD_SETSIZE];
  63. }
  64. }
  65. [StructLayout(LayoutKind.Sequential)]
  66. internal struct WSAData
  67. {
  68. internal short wVersion;
  69. internal short wHighVersion;
  70. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 257)]
  71. internal string szDescription;
  72. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 129)]
  73. internal string szSystemStatus;
  74. internal short iMaxSockets;
  75. internal short iMaxUdpDg;
  76. internal IntPtr lpVendorInfo;
  77. }
  78. public const int FIONREAD = 0x4004667F;
  79. public const int FIONBIO = unchecked((int)0x8004667E);
  80. public const int FIOASYNC = unchecked((int)0x8004667D);
  81. public const int SIOGETEXTENSIONFUNCTIONPOINTER = unchecked((int)0xC8000006);
  82. public const int FD_ALL_EVENTS = (1 << 10) - 1;
  83. private const string WS2_32 = "Ws2_32.dll";
  84. internal class SafeSocketHandle : SafeHandleMinusOneIsInvalid
  85. {
  86. public SafeSocketHandle(IntPtr Handle) : base(false)
  87. {
  88. this.SetHandle(Handle);
  89. }
  90. protected SafeSocketHandle() : base(true) { }
  91. protected override bool ReleaseHandle()
  92. {
  93. // handle released by managed socket
  94. return true;
  95. }
  96. }
  97. [DllImport(WS2_32)]
  98. public extern static int getaddrinfo(IntPtr nodename, IntPtr servname, IntPtr hints, out IntPtr res);
  99. [DllImport(WS2_32)]
  100. public extern static void freeaddrinfo(IntPtr ai);
  101. [DllImport(WS2_32)]
  102. public extern static int ioctlsocket(SafeSocketHandle s, int cmd, ref int argp);
  103. [DllImport(WS2_32)]
  104. public extern static int connect(SafeSocketHandle s, IntPtr name, int namelen);
  105. [DllImport(WS2_32)]
  106. public extern static void WSASetLastError(int iError);
  107. [DllImport(WS2_32)]
  108. public extern static int WSAGetLastError();
  109. [DllImport(WS2_32, CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true, SetLastError = true)]
  110. internal static extern SocketError WSAStartup(
  111. [In] short wVersionRequested,
  112. [Out] out WSAData lpWSAData
  113. );
  114. [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
  115. internal static extern SafeSocketHandle socket(int af, int type, int protocol);
  116. [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
  117. internal static extern int bind(SafeSocketHandle s, IntPtr name, int namelen);
  118. [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
  119. internal static extern int listen(SafeSocketHandle s, int backlog);
  120. [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
  121. internal static extern int select(int nfds, [In, Out] fd_set readfds, [In, Out] fd_set writefds, [In, Out] fd_set exceptfds, ref TimeVal timeout);
  122. [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
  123. internal static extern int send(SafeSocketHandle s, IntPtr buf, int len, int flags);
  124. [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
  125. internal static extern int recv(SafeSocketHandle s, IntPtr buf, int len, int flags);
  126. [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
  127. internal static extern NativeSockets.SafeSocketHandle accept(SafeSocketHandle s, IntPtr name, int namelen);
  128. [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
  129. internal static extern int closesocket(IntPtr s);
  130. [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
  131. internal static extern int shutdown(SafeSocketHandle s, int how);
  132. [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
  133. internal static extern int getsockopt(SafeSocketHandle s, int level, int optname, IntPtr optval, ref int optlen);
  134. [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
  135. internal static extern int setsockopt(SafeSocketHandle s, int level, int optname, IntPtr optval, int optlen);
  136. [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
  137. internal static extern int getpeername(SafeSocketHandle s, IntPtr name, ref int namelen);
  138. [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
  139. internal static extern int getsockname(SafeSocketHandle s, IntPtr name, ref int namelen);
  140. [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
  141. internal static extern int sendto(SafeSocketHandle s, IntPtr buf, int len, int flags, IntPtr to, ref int tolen);
  142. [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
  143. internal static extern int recvfrom(SafeSocketHandle s, IntPtr buf, int len, int flags, IntPtr from, ref int fromlen);
  144. [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
  145. internal static extern int WSAEventSelect(SafeSocketHandle S, SafeWaitHandle hEventObject, int lNetworkEvents);
  146. }
  147. private class SocketData
  148. {
  149. internal Socket Socket;
  150. internal bool IsSelectable = false;
  151. internal bool IsSsl = false;
  152. internal bool IsClosing = false;
  153. public SocketData(Socket socket)
  154. {
  155. Socket = socket;
  156. }
  157. }
  158. bool _isInitialized = false;
  159. Dictionary<int, SocketData> _sockets = new Dictionary<int, SocketData>();
  160. int _handleNext;
  161. const int MaxSockets = 62; //for the call to WaitAny
  162. AutoResetEvent _eventSignalThread;
  163. AutoResetEvent _eventSsl = new AutoResetEvent(false);
  164. Thread _threadWaitForEvents;
  165. int _dwLastError = (int)SocketError.SocketError;
  166. private bool GetSocketData(int socketIndex, out SocketData socketData)
  167. {
  168. socketData = null;
  169. lock(_sockets)
  170. {
  171. if(!_sockets.ContainsKey(socketIndex)) return false;
  172. socketData = _sockets[socketIndex];
  173. }
  174. return true;
  175. }
  176. internal bool GetSocket(int socketIndex, out Socket socket)
  177. {
  178. SocketData sd;
  179. socket = null;
  180. if(!GetSocketData(socketIndex, out sd)) return false;
  181. socket = sd.Socket;
  182. return true;
  183. }
  184. internal void SetSslSocket(int socketIndex)
  185. {
  186. lock(_sockets)
  187. {
  188. if (_sockets.ContainsKey(socketIndex))
  189. {
  190. _sockets[socketIndex].IsSsl = true;
  191. }
  192. }
  193. }
  194. internal void SignalThread()
  195. {
  196. if (_isInitialized)
  197. {
  198. _evtSocketSend.SendTo(new byte[] { 0 }, _evtSocketRecv.LocalEndPoint);
  199. }
  200. }
  201. Socket _evtSocketRecv;
  202. Socket _evtSocketSend;
  203. internal void ClearSocketEvent(int socket, bool fRead)
  204. {
  205. SocketData sd;
  206. if (_isInitialized)
  207. {
  208. if (GetSocketData(socket, out sd))
  209. {
  210. if (fRead)
  211. {
  212. lock (m_read)
  213. {
  214. if (m_read.Contains(sd.Socket))
  215. {
  216. m_read.Remove(sd.Socket);
  217. }
  218. }
  219. }
  220. else
  221. {
  222. lock (m_write)
  223. {
  224. if (m_write.Contains(sd.Socket))
  225. {
  226. m_write.Remove(sd.Socket);
  227. }
  228. }
  229. }
  230. }
  231. SignalThread();
  232. }
  233. }
  234. bool _socketsShuttingDown = false;
  235. List<Socket> m_read = new List<Socket>();
  236. List<Socket> m_write = new List<Socket>();
  237. List<Socket> m_excpt = new List<Socket>();
  238. void WaitForNetworkEvents()
  239. {
  240. List<Socket> read = new List<Socket>();
  241. List<Socket> write = new List<Socket>();
  242. List<Socket> excpt = new List<Socket>();
  243. read.Add(_evtSocketRecv);
  244. //check for emulator exit..
  245. while (!this.Emulator.IsShuttingDown && !_socketsShuttingDown)
  246. {
  247. Socket.Select(read, write, excpt, 0x7fffffff );
  248. if (_socketsShuttingDown) return;
  249. if (read.Contains(_evtSocketRecv))
  250. {
  251. EndPoint ep = _evtSocketSend.LocalEndPoint;
  252. byte[] data = new byte[256];
  253. _evtSocketRecv.ReceiveFrom(data, ref ep);
  254. read.Remove(_evtSocketRecv);
  255. }
  256. lock (_sockets)
  257. {
  258. lock (m_read)
  259. {
  260. for (int i = 0; i < read.Count; i++)
  261. {
  262. m_read.Add(read[i]);
  263. }
  264. }
  265. lock (m_write)
  266. {
  267. for (int i = 0; i < write.Count; i++)
  268. {
  269. m_write.Add(write[i]);
  270. }
  271. }
  272. lock (m_excpt)
  273. {
  274. for (int i = 0; i < excpt.Count; i++)
  275. {
  276. m_excpt.Add(excpt[i]);
  277. }
  278. }
  279. List<int> removeList = new List<int>();
  280. read.Clear();
  281. write.Clear();
  282. excpt.Clear();
  283. read.Add(_evtSocketRecv);
  284. foreach (int handle in _sockets.Keys)
  285. {
  286. SocketData socket = _sockets[handle];
  287. if (socket.IsClosing)
  288. {
  289. removeList.Add(handle);
  290. Socket sock = socket.Socket;
  291. lock (m_read)
  292. {
  293. if (m_read.Contains(sock))
  294. {
  295. m_read.Remove(sock);
  296. }
  297. }
  298. lock (m_write)
  299. {
  300. if (m_write.Contains(sock))
  301. {
  302. m_write.Remove(sock);
  303. }
  304. }
  305. lock (m_excpt)
  306. {
  307. if (m_excpt.Contains(sock))
  308. {
  309. m_excpt.Remove(sock);
  310. }
  311. }
  312. continue;
  313. }
  314. if (socket.IsSelectable)
  315. {
  316. try
  317. {
  318. Socket sock = socket.Socket;
  319. if (!m_read.Contains(sock))
  320. {
  321. read.Add(sock);
  322. }
  323. if (!m_write.Contains(sock))
  324. {
  325. write.Add(sock);
  326. }
  327. if (!m_excpt.Contains(sock))
  328. {
  329. excpt.Add(sock);
  330. }
  331. }
  332. catch
  333. {
  334. }
  335. }
  336. }
  337. foreach (int handle in removeList)
  338. {
  339. try
  340. {
  341. _sockets[handle].Socket.Close();
  342. }
  343. catch
  344. {
  345. }
  346. _sockets.Remove(handle);
  347. }
  348. }
  349. this.Emulator.SetSystemEvents(Events.SystemEvents.SOCKET);
  350. }
  351. }
  352. [MethodImplAttribute(MethodImplOptions.Synchronized)]
  353. void EnsureInitialized()
  354. {
  355. if (!_isInitialized)
  356. {
  357. short wVersion = 0x0202;
  358. NativeSockets.WSAData wsaData = new NativeSockets.WSAData();
  359. SocketError err = NativeSockets.WSAStartup(wVersion, out wsaData);
  360. if (err != SocketError.Success)
  361. throw new SocketException((int)err);
  362. _eventSignalThread = new AutoResetEvent(false);
  363. _evtSocketRecv = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
  364. _evtSocketRecv.Bind(new IPEndPoint(IPAddress.Loopback, 0));
  365. _evtSocketSend = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
  366. _evtSocketSend.Bind(new IPEndPoint(IPAddress.Loopback, 0));
  367. _threadWaitForEvents = new Thread(new ThreadStart(WaitForNetworkEvents));
  368. _threadWaitForEvents.Start();
  369. _isInitialized = true;
  370. }
  371. }
  372. int RegisterSocket(Socket socket)
  373. {
  374. return RegisterSocket(socket, false);
  375. }
  376. [MethodImplAttribute(MethodImplOptions.Synchronized)]
  377. int RegisterSocket( Socket socket, bool isSelectable)
  378. {
  379. if (_sockets.Count == MaxSockets)
  380. {
  381. return ReturnError(SocketError.TooManyOpenSockets);
  382. }
  383. int handle;
  384. lock(_sockets)
  385. {
  386. handle = ++_handleNext;
  387. _sockets[handle] = new SocketData( socket );
  388. _sockets[handle].IsSelectable = (isSelectable || socket.ProtocolType != ProtocolType.Tcp);
  389. }
  390. SignalThread();
  391. return handle;
  392. }
  393. [MethodImplAttribute(MethodImplOptions.Synchronized)]
  394. internal void UnregisterSocket(int handle)
  395. {
  396. lock(_sockets)
  397. {
  398. if(!_sockets.ContainsKey(handle)) return;
  399. _sockets[handle].IsClosing = true;
  400. SignalThread();
  401. }
  402. }
  403. internal int ReturnError(SocketError error)
  404. {
  405. _dwLastError = (int)error;
  406. return (int)SocketError.SocketError;
  407. }
  408. void StoreLastError()
  409. {
  410. _dwLastError = NativeSockets.WSAGetLastError();
  411. }
  412. TinyCLRSockets.fd_set IntPtrToTinyCLRFdSet(IntPtr fds)
  413. {
  414. TinyCLRSockets.fd_set fd_set = null;
  415. if (fds != IntPtr.Zero)
  416. {
  417. fd_set = new TinyCLRSockets.fd_set();
  418. Marshal.PtrToStructure(fds, fd_set);
  419. }
  420. return fd_set;
  421. }
  422. bool TinyCLRFdSetToFdSet(TinyCLRSockets.fd_set fd_setsrc, out List<Socket> fd_setDst)
  423. {
  424. bool fRes = true;
  425. fd_setDst = null;
  426. if (fd_setsrc != null)
  427. {
  428. fd_setDst = new List<Socket>();
  429. for (int i = 0; i < fd_setsrc.count; i++)
  430. {
  431. SocketData sd;
  432. if(!GetSocketData(fd_setsrc.fd_array[i], out sd))
  433. {
  434. fRes = false;
  435. break;
  436. }
  437. if(sd.IsSelectable)
  438. {
  439. fd_setDst.Add(sd.Socket);
  440. }
  441. }
  442. }
  443. return fRes;
  444. }
  445. bool FilterFd_set(List<Socket> fdNative, TinyCLRSockets.fd_set fdCLR)
  446. {
  447. if (fdNative != null)
  448. {
  449. Debug.Assert(fdCLR != null);
  450. for (int i = 0; i < fdCLR.count; )
  451. {
  452. bool fSet = false;
  453. Socket sock = null;
  454. if(!GetSocket(fdCLR.fd_array[i], out sock)) return false;
  455. for (int j = 0; j < fdNative.Count; j++)
  456. {
  457. if (fdNative[j] == sock)
  458. {
  459. fSet = true;
  460. break;
  461. }
  462. }
  463. if (!fSet)
  464. {
  465. Array.Copy(fdCLR.fd_array, i + 1, fdCLR.fd_array, i, fdCLR.count - i - 1);
  466. fdCLR.count--;
  467. }
  468. else
  469. {
  470. i++;
  471. }
  472. }
  473. }
  474. return true;
  475. }
  476. void TinyCLRFdSetToIntPtr(TinyCLRSockets.fd_set fd_set, IntPtr fds)
  477. {
  478. if (fds != IntPtr.Zero)
  479. {
  480. Marshal.StructureToPtr(fd_set, fds, true);
  481. }
  482. }
  483. private uint IPAddressToUint(IPAddress address)
  484. {
  485. uint ret = 0;
  486. if (address != null)
  487. {
  488. byte[] bytes = address.GetAddressBytes();
  489. Debug.Assert(address.AddressFamily == AddressFamily.InterNetwork);
  490. Debug.Assert(bytes != null);
  491. Debug.Assert(bytes.Length == 4);
  492. ret = BitConverter.ToUInt32(bytes, 0);
  493. }
  494. return ret;
  495. }
  496. private bool IsIPAddressIPv4(IPAddress address)
  497. {
  498. if (address.AddressFamily == AddressFamily.InterNetwork)
  499. return true;
  500. return false;
  501. }
  502. #region ISocketsDriver
  503. bool ISocketsDriver.Initialize()
  504. {
  505. EnsureInitialized();
  506. return true;
  507. }
  508. bool ISocketsDriver.Uninitialize()
  509. {
  510. if (_isInitialized)
  511. {
  512. _socketsShuttingDown = true;
  513. SignalThread();
  514. lock (_sockets)
  515. {
  516. foreach (SocketData sd in _sockets.Values)
  517. {
  518. try
  519. {
  520. sd.Socket.Close();
  521. }
  522. catch
  523. {
  524. }
  525. }
  526. _sockets.Clear();
  527. }
  528. try
  529. {
  530. _evtSocketRecv.Close();
  531. _evtSocketSend.Close();
  532. }
  533. catch
  534. {
  535. }
  536. _isInitialized = false;
  537. }
  538. return true;
  539. }
  540. int ISocketsDriver.socket(int family, int type, int protocol)
  541. {
  542. Socket socket = null;
  543. try
  544. {
  545. socket = new Socket((AddressFamily)family, (SocketType)type, (ProtocolType)protocol);
  546. // always make emulator sockets blocking so that the NetworkStream will work (for SSL)
  547. socket.Blocking = true;
  548. }
  549. catch( SocketException se )
  550. {
  551. return ReturnError(se.SocketErrorCode);
  552. }
  553. catch
  554. {
  555. return ReturnError(SocketError.SocketError);
  556. }
  557. if (socket == null) return ReturnError(SocketError.SocketError);
  558. return RegisterSocket(socket, ((ProtocolType)protocol != ProtocolType.Tcp));
  559. }
  560. int ISocketsDriver.bind(int socket, IntPtr address, int addressLen)
  561. {
  562. SocketData sd = null;
  563. if (!GetSocketData(socket, out sd)) return ReturnError(SocketError.NotSocket);
  564. try
  565. {
  566. SockAddr sa = new SockAddr();
  567. sa.MarshalFromNative(address);
  568. if (sa.sin_port == 80)
  569. {
  570. sa.sin_port++;
  571. }
  572. IPEndPoint ep = new IPEndPoint(sa.sin_addr, sa.sin_port);
  573. sd.Socket.Bind(ep);
  574. }
  575. catch (SocketException se)
  576. {
  577. return ReturnError(se.SocketErrorCode);
  578. }
  579. catch
  580. {
  581. return ReturnError(SocketError.SocketError);
  582. }
  583. return (int)SocketError.Success;
  584. }
  585. int ISocketsDriver.connect(int socket, IntPtr address, int addressLen)
  586. {
  587. Socket sock = null;
  588. if (!GetSocket(socket, out sock)) return ReturnError(SocketError.NotSocket);
  589. try
  590. {
  591. SockAddr sa = new SockAddr();
  592. sa.MarshalFromNative(address);
  593. sock.BeginConnect(new IPEndPoint(sa.sin_addr, sa.sin_port), new AsyncCallback(EndSockConnect), socket);
  594. }
  595. catch( SocketException se )
  596. {
  597. return ReturnError(se.SocketErrorCode);
  598. }
  599. catch
  600. {
  601. return ReturnError(SocketError.SocketError);
  602. }
  603. return ReturnError(SocketError.WouldBlock);
  604. }
  605. void EndSockConnect(IAsyncResult iar)
  606. {
  607. int socket = (int)iar.AsyncState;
  608. SocketData sd = null;
  609. if (!GetSocketData(socket, out sd)) return;
  610. try
  611. {
  612. sd.IsSelectable = true;
  613. sd.Socket.EndConnect(iar);
  614. }
  615. catch
  616. {
  617. }
  618. SignalThread();
  619. }
  620. int ISocketsDriver.send(int socket, IntPtr buf, int len, int flags)
  621. {
  622. SocketData sd = null;
  623. if (!GetSocketData(socket, out sd)) return ReturnError(SocketError.NotSocket);
  624. try
  625. {
  626. if (sd.Socket.Poll(0, SelectMode.SelectWrite))
  627. {
  628. byte[] data = new byte[len];
  629. int sent = 0;
  630. Marshal.Copy(buf, data, 0, len);
  631. sent = sd.Socket.Send(data, 0, len, (SocketFlags)flags);
  632. ClearSocketEvent(socket, false);
  633. return sent;
  634. }
  635. }
  636. catch (SocketException se)
  637. {
  638. return ReturnError((SocketError)se.ErrorCode);
  639. }
  640. return ReturnError(SocketError.WouldBlock);
  641. }
  642. int ISocketsDriver.recv(int socket, IntPtr buf, int len, int flags)
  643. {
  644. int ret = ReturnError(SocketError.WouldBlock);
  645. SocketData sd = null;
  646. if (!GetSocketData(socket, out sd)) return ReturnError(SocketError.NotSocket);
  647. try
  648. {
  649. if (sd.Socket.Poll(0, SelectMode.SelectRead))
  650. {
  651. byte[] data = new byte[len];
  652. int read = 0;
  653. read = sd.Socket.Receive(data, 0, len, (SocketFlags)flags);
  654. Marshal.Copy(data, 0, buf, read);
  655. return read;
  656. }
  657. }
  658. catch (SocketException se)
  659. {
  660. return ReturnError((SocketError)se.ErrorCode);
  661. }
  662. finally
  663. {
  664. ClearSocketEvent(socket, true);
  665. }
  666. return ReturnError(SocketError.WouldBlock);
  667. }
  668. int ISocketsDriver.close(int socket)
  669. {
  670. int ret = (int)SocketError.Success;
  671. SocketData sd = null;
  672. if (!GetSocketData(socket, out sd)) return ReturnError(SocketError.NotSocket);
  673. try
  674. {
  675. if (sd.IsSsl)
  676. {
  677. Hal.Ssl.CloseSocket(socket);
  678. }
  679. UnregisterSocket(socket);
  680. }
  681. catch (SocketException se)
  682. {
  683. ret = ReturnError(se.SocketErrorCode);
  684. }
  685. catch
  686. {
  687. ret = ReturnError(SocketError.SocketError);
  688. }
  689. return ret;
  690. }
  691. int ISocketsDriver.accept(int socket, IntPtr address, ref int addressLen)
  692. {
  693. Socket sock = null;
  694. if (!GetSocket(socket, out sock)) return ReturnError(SocketError.NotSocket);
  695. try
  696. {
  697. IAsyncResult iar = sock.BeginAccept(null, null);
  698. iar.AsyncWaitHandle.WaitOne();
  699. Socket sockAccept = sock.EndAccept(iar);
  700. int newSock = RegisterSocket(sockAccept, true);
  701. ClearSocketEvent(socket, true);
  702. return newSock;
  703. }
  704. catch (SocketException se)
  705. {
  706. return ReturnError(se.SocketErrorCode);
  707. }
  708. catch
  709. {
  710. return ReturnError(SocketError.SocketError);
  711. }
  712. }
  713. int ISocketsDriver.listen(int socket, int backlog)
  714. {
  715. SocketData sd = null;
  716. if (!GetSocketData(socket, out sd)) return ReturnError(SocketError.NotSocket);
  717. int ret = (int)SocketError.Success;
  718. try
  719. {
  720. sd.Socket.Listen(backlog);
  721. sd.IsSelectable = true;
  722. SignalThread();
  723. }
  724. catch (SocketException se)
  725. {
  726. ret = ReturnError(se.SocketErrorCode);
  727. }
  728. catch
  729. {
  730. ret = ReturnError(SocketError.SocketError);
  731. }
  732. return ret;
  733. }
  734. int ISocketsDriver.shutdown(int socket, int how)
  735. {
  736. int ret = (int)SocketError.Success;
  737. Socket sock = null;
  738. if (!GetSocket(socket, out sock)) return ReturnError(SocketError.NotSocket);
  739. try
  740. {
  741. sock.Shutdown( (SocketShutdown)how );
  742. SignalThread();
  743. }
  744. catch (SocketException se)
  745. {
  746. ret = ReturnError(se.SocketErrorCode);
  747. }
  748. catch
  749. {
  750. ret = ReturnError(SocketError.SocketError);
  751. }
  752. return ret;
  753. }
  754. int ISocketsDriver.getaddrinfo(IntPtr nodename, IntPtr servname, IntPtr hints, out IntPtr res)
  755. {
  756. res = IntPtr.Zero;
  757. int ret = NativeSockets.getaddrinfo(nodename, servname, hints, out res);
  758. StoreLastError();
  759. return ret;
  760. }
  761. void ISocketsDriver.freeaddrinfo(IntPtr ai)
  762. {
  763. NativeSockets.freeaddrinfo(ai);
  764. }
  765. int ISocketsDriver.ioctl(int socket, int cmd, ref int data)
  766. {
  767. Socket sock = null;
  768. if (!GetSocket(socket, out sock)) return ReturnError(SocketError.NotSocket);
  769. int ret = (int)SocketError.Success;
  770. try
  771. {
  772. if (cmd == NativeSockets.FIONBIO)
  773. {
  774. }
  775. else if (cmd == NativeSockets.FIONREAD)
  776. {
  777. data = sock.Available;
  778. }
  779. else
  780. {
  781. ret = (int)SocketError.SocketError;
  782. }
  783. }
  784. catch (SocketException se)
  785. {
  786. ret = ReturnError(se.SocketErrorCode);
  787. }
  788. catch
  789. {
  790. ret = ReturnError(SocketError.SocketError);
  791. }
  792. return ret;
  793. }
  794. int ISocketsDriver.getlasterror()
  795. {
  796. return _dwLastError;
  797. }
  798. private void InternalSelect(List<Socket> read, List<Socket> write, List<Socket> excpt)
  799. {
  800. if (read != null)
  801. {
  802. for (int i = read.Count - 1; i >= 0; i--)
  803. {
  804. if (!m_read.Contains(read[i]))
  805. {
  806. read.RemoveAt(i);
  807. }
  808. }
  809. }
  810. if (write != null)
  811. {
  812. for (int i = write.Count - 1; i >= 0; i--)
  813. {
  814. if (!m_write.Contains(write[i]))
  815. {
  816. write.RemoveAt(i);
  817. }
  818. }
  819. }
  820. if (excpt != null)
  821. {
  822. for (int i = excpt.Count - 1; i >= 0; i--)
  823. {
  824. if (!m_excpt.Contains(excpt[i]))
  825. {
  826. excpt.RemoveAt(i);
  827. }
  828. }
  829. }
  830. }
  831. [MethodImplAttribute(MethodImplOptions.Synchronized)]
  832. int ISocketsDriver.select(int nfds, IntPtr readfds, IntPtr writefds, IntPtr exceptfds, ref TimeVal timeout)
  833. {
  834. List<Socket> readList;
  835. List<Socket> writeList;
  836. List<Socket> exceptList;
  837. int ret = 0;
  838. TinyCLRSockets.fd_set read = IntPtrToTinyCLRFdSet(readfds);
  839. TinyCLRSockets.fd_set write = IntPtrToTinyCLRFdSet(writefds);
  840. TinyCLRSockets.fd_set except = IntPtrToTinyCLRFdSet(exceptfds);
  841. if (!TinyCLRFdSetToFdSet(read, out readList)) return ReturnError(SocketError.NotSocket);
  842. if (!TinyCLRFdSetToFdSet(write, out writeList)) return ReturnError(SocketError.NotSocket);
  843. if (!TinyCLRFdSetToFdSet(except, out exceptList)) return ReturnError(SocketError.NotSocket);
  844. if ((readList != null && readList.Count > 0) ||
  845. (writeList != null && writeList.Count > 0) ||
  846. (exceptList != null && exceptList.Count > 0))
  847. {
  848. try
  849. {
  850. //Socket.Select(readList, writeList, exceptList, timeout.tv_usec);
  851. InternalSelect(readList, writeList, exceptList);
  852. }
  853. catch (SocketException se)
  854. {
  855. ret = ReturnError(se.SocketErrorCode);
  856. }
  857. }
  858. if (!FilterFd_set(readList, read)) return ReturnError(SocketError.NotSocket);
  859. if (!FilterFd_set(writeList, write)) return ReturnError(SocketError.NotSocket);
  860. if (!FilterFd_set(exceptList, except)) return ReturnError(SocketError.NotSocket);
  861. TinyCLRFdSetToIntPtr(read, readfds);
  862. TinyCLRFdSetToIntPtr(write, writefds);
  863. TinyCLRFdSetToIntPtr(except, exceptfds);
  864. if(ret != (int)SocketError.SocketError)
  865. {
  866. if (readList != null) ret += readList.Count;
  867. if (writeList != null) ret += writeList.Count;
  868. if (exceptList != null) ret += exceptList.Count;
  869. }
  870. return ret;
  871. }
  872. int ISocketsDriver.setsockopt(int socket, int level, int optname, IntPtr optval, int optlen)
  873. {
  874. Socket sock = null;
  875. if (!GetSocket(socket, out sock)) return ReturnError(SocketError.NotSocket);
  876. int ret = (int)SocketError.Success;
  877. try
  878. {
  879. byte []data = new byte[optlen];
  880. if (level == (int)SocketOptionLevel.Socket && optname == (int)SocketOptionName.Linger && optlen == 4)
  881. {
  882. int linger = Marshal.ReadInt32(optval);
  883. LingerOption li = new LingerOption(linger != -1, linger < 0 ? 10 : linger);
  884. Array.Copy(BitConverter.GetBytes((UInt16)(li.Enabled ? 1 : 0)), 0, data, 0, 2);
  885. Array.Copy(BitConverter.GetBytes((UInt16)li.LingerTime ), 0, data, 2, 2);
  886. }
  887. else
  888. {
  889. Marshal.Copy(optval, data, 0, optlen);
  890. }
  891. sock.SetSocketOption((SocketOptionLevel)level, (SocketOptionName)optname, data);
  892. }
  893. catch (SocketException se)
  894. {
  895. ret = ReturnError(se.SocketErrorCode);
  896. }
  897. return ret;
  898. }
  899. int ISocketsDriver.getsockopt(int socket, int level, int optname, IntPtr optval, ref int optlen)
  900. {
  901. Socket sock = null;
  902. if (!GetSocket(socket, out sock)) return ReturnError(SocketError.NotSocket);
  903. int ret = (int)SocketError.Success;
  904. try
  905. {
  906. byte[] data = new byte[optlen];
  907. sock.GetSocketOption((SocketOptionLevel)level, (SocketOptionName)optname, data);
  908. if (level == (int)SocketOptionLevel.Socket && optname == (int)SocketOptionName.Linger && optlen == 4)
  909. {
  910. // if linger option is off, then we translate to -1 for the MF option
  911. if(data[0] == 0 && data[1] == 0)
  912. {
  913. Marshal.WriteInt32(optval, -1);
  914. }
  915. else
  916. {
  917. // convert back to a single integer value
  918. Marshal.WriteInt32(optval, (int)BitConverter.ToInt16(data, 2));
  919. }
  920. }
  921. else
  922. {
  923. Marshal.Copy(data, 0, optval, optlen);
  924. }
  925. }
  926. catch (SocketException se)
  927. {
  928. ret = ReturnError(se.SocketErrorCode);
  929. }
  930. return ret;
  931. }
  932. int ISocketsDriver.getpeername(int socket, IntPtr name, ref int namelen)
  933. {
  934. Socket sock = null;
  935. if (!GetSocket(socket, out sock)) return ReturnError(SocketError.NotSocket);
  936. int ret = (int)SocketError.Success;
  937. try
  938. {
  939. IPEndPoint ep = sock.RemoteEndPoint as IPEndPoint;
  940. SockAddr addr = new SockAddr();
  941. addr.sin_addr = IPAddressToUint(ep.Address);
  942. addr.sin_family = (short)ep.AddressFamily;
  943. addr.sin_port = (ushort)ep.Port;
  944. addr.MarshalToNative(name);
  945. }
  946. catch (SocketException se)
  947. {
  948. ret = ReturnError(se.SocketErrorCode);
  949. }
  950. return ret;
  951. }
  952. int ISocketsDriver.getsockname(int socket, IntPtr name, ref int namelen)
  953. {
  954. Socket sock = null;
  955. if (!GetSocket(socket, out sock)) return ReturnError(SocketError.NotSocket);
  956. int ret = (int)SocketError.Success;
  957. try
  958. {
  959. IPEndPoint ep = sock.LocalEndPoint as IPEndPoint;
  960. SockAddr addr = new SockAddr();
  961. if (IPAddress.IsLoopback(ep.Address))
  962. {
  963. addr.sin_addr = IPAddressToUint(ep.Address);
  964. }
  965. else
  966. {
  967. IPHostEntry ipEntry = Dns.GetHostEntry(ep.Address);
  968. for (int i = 0; i < ipEntry.AddressList.Length; i++)
  969. {
  970. if (ipEntry.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
  971. {
  972. addr.sin_addr = IPAddressToUint(ipEntry.AddressList[i]);
  973. }
  974. }
  975. }
  976. addr.sin_family = (short)ep.AddressFamily;
  977. addr.sin_port = (ushort)ep.Port;
  978. addr.MarshalToNative(name);
  979. }
  980. catch (SocketException se)
  981. {
  982. ret = ReturnError(se.SocketErrorCode);
  983. }
  984. return ret;
  985. }
  986. int ISocketsDriver.sendto(int socket, IntPtr buf, int len, int flags, IntPtr to, ref int tolen)
  987. {
  988. SocketData sd = null;
  989. if (!GetSocketData(socket, out sd)) return ReturnError(SocketError.NotSocket);
  990. try
  991. {
  992. if (sd.Socket.Poll(0, SelectMode.SelectWrite))
  993. {
  994. byte[] data = new byte[len];
  995. int sent = 0;
  996. Marshal.Copy(buf, data, 0, len);
  997. SockAddr toAddr = new SockAddr();
  998. toAddr.MarshalFromNative(to);
  999. IPEndPoint toEP = new IPEndPoint(toAddr.sin_addr, toAddr.sin_port);
  1000. sent = sd.Socket.SendTo(data, 0, len, (SocketFlags)flags, toEP);
  1001. ClearSocketEvent(socket, false);
  1002. return sent;
  1003. }
  1004. }
  1005. catch (SocketException se)
  1006. {
  1007. return ReturnError((SocketError)se.ErrorCode);
  1008. }
  1009. return ReturnError(SocketError.WouldBlock);
  1010. }
  1011. int ISocketsDriver.recvfrom(int socket, IntPtr buf, int len, int flags, IntPtr from, ref int fromlen)
  1012. {
  1013. SocketData sd = null;
  1014. if (!GetSocketData(socket, out sd)) return ReturnError(SocketError.NotSocket);
  1015. try
  1016. {
  1017. if (sd.Socket.Poll(0, SelectMode.SelectRead))
  1018. {
  1019. byte[] data = new byte[len];
  1020. int read = 0;
  1021. SockAddr fromAddr = new SockAddr();
  1022. fromAddr.MarshalFromNative(from);
  1023. EndPoint fromEP = new IPEndPoint(fromAddr.sin_addr, fromAddr.sin_port);
  1024. read = sd.Socket.ReceiveFrom(data, 0, len, (SocketFlags)flags, ref fromEP);
  1025. Marshal.Copy(data, 0, buf, read);
  1026. fromAddr.sin_addr = IPAddressToUint(((IPEndPoint)fromEP).Address);
  1027. fromAddr.sin_port = (ushort)((IPEndPoint)fromEP).Port;
  1028. fromAddr.sin_family = (short)((IPEndPoint)fromEP).AddressFamily;
  1029. fromAddr.MarshalToNative(from);
  1030. return read;
  1031. }
  1032. }
  1033. catch (SocketException se)
  1034. {
  1035. return ReturnError((SocketError)se.ErrorCode);
  1036. }
  1037. finally
  1038. {
  1039. ClearSocketEvent(socket, true);
  1040. }
  1041. return ReturnError(SocketError.WouldBlock);
  1042. }
  1043. uint ISocketsDriver.NetworkAdapterCount
  1044. {
  1045. get
  1046. {
  1047. return (uint)NetworkInterface.GetAllNetworkInterfaces().Length;
  1048. }
  1049. }
  1050. int ISocketsDriver.LoadAdapterConfiguration(uint interfaceIndex, ref NetworkAdapterConfiguration config)
  1051. {
  1052. NetworkInterface networkInterface = NetworkInterface.GetAllNetworkInterfaces()[interfaceIndex];
  1053. IPInterfaceProperties props = networkInterface.GetIPProperties();
  1054. IPv4InterfaceProperties ipv4props = null;
  1055. try
  1056. {
  1057. ipv4props = props.GetIPv4Properties();
  1058. }
  1059. catch(NetworkInformationException)
  1060. {
  1061. }
  1062. if (ipv4props != null)
  1063. {
  1064. if (props.IsDynamicDnsEnabled)
  1065. {
  1066. config.flags |= NetworkAdapterConfiguration.FLAGS_DYNAMIC_DNS;
  1067. }
  1068. if (ipv4props.IsDhcpEnabled)
  1069. {
  1070. config.flags |= NetworkAdapterConfiguration.FLAGS_DHCP;
  1071. }
  1072. for (int iAddress = 0; iAddress < props.UnicastAddresses.Count; iAddress++)
  1073. {
  1074. UnicastIPAddressInformation unicastAddress = props.UnicastAddresses[iAddress];
  1075. if (IsIPAddressIPv4(unicastAddress.Address))
  1076. {
  1077. config.ipaddr = this.IPAddressToUint(unicastAddress.Address);
  1078. config.subnetmask = this.IPAddressToUint(unicastAddress.IPv4Mask);
  1079. break;
  1080. }
  1081. }
  1082. for (int iAddress = 0; iAddress < props.GatewayAddresses.Count; iAddress++)
  1083. {
  1084. GatewayIPAddressInformation gatewayAddress = props.GatewayAddresses[iAddress];
  1085. if (IsIPAddressIPv4(gatewayAddress.Address))
  1086. {
  1087. config.gateway = this.IPAddressToUint(gatewayAddress.Address);
  1088. break;
  1089. }
  1090. }
  1091. int dnsServerIndex = 0;
  1092. for (int iAddress = 0; iAddress < props.DnsAddresses.Count && dnsServerIndex < 2; iAddress++)
  1093. {
  1094. IPAddress address = props.DnsAddresses[iAddress];
  1095. if (IsIPAddressIPv4(address))
  1096. {
  1097. switch(dnsServerIndex)
  1098. {
  1099. case 0:
  1100. config.dnsServer1 = this.IPAddressToUint(address);
  1101. break;
  1102. case 1:
  1103. config.dnsServer2 = this.IPAddressToUint(address);
  1104. break;
  1105. }
  1106. dnsServerIndex++;
  1107. }
  1108. }
  1109. PhysicalAddress macAddress = networkInterface.GetPhysicalAddress();
  1110. byte[] macBytes = macAddress.GetAddressBytes();
  1111. config.networkInterfaceType = (uint)networkInterface.NetworkInterfaceType;
  1112. config.networkAddressLen = (uint)macBytes.Length;
  1113. unsafe
  1114. {
  1115. fixed (byte* p = config.networkAddressBuf)
  1116. {
  1117. Marshal.Copy(macBytes, 0, new IntPtr(p), macBytes.Length);
  1118. }
  1119. }
  1120. }
  1121. return 0;
  1122. }
  1123. int ISocketsDriver.UpdateAdapterConfiguration(uint interfaceIndex, uint updateFlags, ref NetworkAdapterConfiguration config)
  1124. {
  1125. //CLR_E_FAIL. Update with better error?
  1126. unchecked { return (int)(uint)CLR_ERRORCODE.CLR_E_FAIL; }
  1127. }
  1128. #endregion
  1129. }
  1130. internal class ComPortSocket : ComPortToAsyncStream
  1131. {
  1132. Socket _socket;
  1133. public ComPortSocket(Socket socket)
  1134. : base(new NetworkStream(socket))
  1135. {
  1136. _socket = socket;
  1137. }
  1138. public override int AvailableBytes
  1139. {
  1140. get
  1141. {
  1142. return _socket.Available;
  1143. }
  1144. }
  1145. }
  1146. internal class TcpListenerForDebugAPI : EmulatorComponent
  1147. {
  1148. //defined in unmanaged code somewhere??
  1149. //also in debugger.dll somewhere??
  1150. //Should Emulator depend on Debugger.dll? Can then use PortDefinition_Tcp.DefaultPort
  1151. //and use Streams, instead of copy/pasted code?
  1152. const int DEBUG_PORT = 26000;
  1153. TcpListener _tcpListener;
  1154. TcpClient _tcpClient;
  1155. int _port = DEBUG_PORT;
  1156. ComPortHandle _comPortHandle = ComPortHandle.DebugPort;
  1157. public override void SetupComponent()
  1158. {
  1159. //Is this right???
  1160. base.SetupComponent();
  1161. _tcpListener = new TcpListener(IPAddress.Any, _port);
  1162. this.Emulator.ComPortCollection.CollectionChanged += new System.ComponentModel.CollectionChangeEventHandler(OnComPortCollectionChanged);
  1163. StartListener();
  1164. }
  1165. private void OnComPortCollectionChanged(object sender, CollectionChangeEventArgs args)
  1166. {
  1167. if (args.Action == CollectionChangeAction.Remove)
  1168. {
  1169. ComPort comPort = (ComPort)args.Element;
  1170. ComPortHandle handle = comPort.ComPortHandle;
  1171. if (handle == _comPortHandle)
  1172. {
  1173. StartListener();
  1174. }
  1175. }
  1176. }
  1177. [MethodImplAttribute(MethodImplOptions.Synchronized)]
  1178. void StartListener()
  1179. {
  1180. try
  1181. {
  1182. //should this support both debug ports? Or just one per port?
  1183. _tcpListener.Start(1);
  1184. _tcpListener.BeginAcceptSocket(new AsyncCallback(AcceptSocket), null);
  1185. }
  1186. catch
  1187. {
  1188. }
  1189. }
  1190. [MethodImplAttribute(MethodImplOptions.Synchronized)]
  1191. public override void UninitializeComponent()
  1192. {
  1193. base.UninitializeComponent();
  1194. try
  1195. {
  1196. _tcpListener.Stop();
  1197. if (_tcpClient != null)
  1198. {
  1199. _tcpClient.Close();
  1200. _tcpClient = null;
  1201. }
  1202. }
  1203. catch
  1204. {
  1205. }
  1206. }
  1207. [MethodImplAttribute(MethodImplOptions.Synchronized)]
  1208. private void AcceptSocket(IAsyncResult ar)
  1209. {
  1210. try
  1211. {
  1212. // End the operation and display the received data on
  1213. // the console.
  1214. Socket client = _tcpListener.EndAcceptSocket(ar);
  1215. client.NoDelay = true;
  1216. ComPortSocket comPortSocket = new ComPortSocket(client/*, this*/);
  1217. comPortSocket.ComPortHandle = _comPortHandle;
  1218. //This doesn't seem right. ComPort should have an Initialize that starts read?
  1219. //who cares if the Device calls initialize??????
  1220. comPortSocket.DeviceInitialize();
  1221. this.Emulator.RegisterComponent(comPortSocket);
  1222. _tcpListener.Stop();
  1223. }
  1224. catch
  1225. {
  1226. }
  1227. }
  1228. }
  1229. }