PageRenderTime 30ms CodeModel.GetById 0ms RepoModel.GetById 1ms app.codeStats 0ms

/Backend/Modules/_socket.cs

https://bitbucket.org/AdamMil/boaold
C# | 354 lines | 274 code | 59 blank | 21 comment | 7 complexity | 7cdf7f0d1268d133ed86213c47d37952 MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. Boa is the reference implementation for a language similar to Python,
  3. also called Boa. This implementation is both interpreted and compiled,
  4. targeting the Microsoft .NET Framework.
  5. http://www.adammil.net/
  6. Copyright (C) 2004-2005 Adam Milazzo
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19. using System;
  20. using System.Net;
  21. using System.Net.Sockets;
  22. using Boa.Runtime;
  23. namespace Boa.Modules
  24. {
  25. [BoaType("module")]
  26. public sealed class _socket
  27. { _socket() { }
  28. #region Support classes
  29. public class error : RuntimeException
  30. { public error(int code, string message) : base(message) { this.code=code; }
  31. public error(string message) : base(message) { }
  32. public int code;
  33. }
  34. public class herror : error
  35. { public herror(int code, string message) : base(code, message) { }
  36. public herror(string message) : base(message) { }
  37. }
  38. public class gaierror : error
  39. { public gaierror(int code, string message) : base(code, message) { }
  40. public gaierror(string message) : base(message) { }
  41. }
  42. public class timeout : error
  43. { public timeout() : base("timed out") { }
  44. }
  45. // TODO: support IPv6 addresses
  46. public class socket
  47. { public socket() : this(AF_INET, SOCK_STREAM, 0) { }
  48. public socket(int family) : this(family, SOCK_STREAM, 0) { }
  49. public socket(int family, int type) : this(family, type, 0) { }
  50. public socket(int family, int type, int proto) :
  51. this((AddressFamily)family, (SocketType)type, (ProtocolType)proto) { }
  52. public socket(AddressFamily family, SocketType type, ProtocolType proto)
  53. { try { Socket = new Socket(family, type, proto); }
  54. catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
  55. catch(Exception e) { throw new error(e.Message); }
  56. }
  57. public socket(Socket socket) { Socket=socket; }
  58. public bool connected { get { return Socket.Connected; } }
  59. public int waiting { get { return Socket.Available; } }
  60. public Tuple accept()
  61. { try
  62. { socket s = new socket(Socket.Accept());
  63. return new Tuple(s, s.getpeername());
  64. }
  65. catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
  66. catch(Exception e) { throw new error(e.Message); }
  67. }
  68. public void bind(Tuple address)
  69. { try { Socket.Bind(AddressToEndpoint(address)); }
  70. catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
  71. catch(Exception e) { throw new error(e.Message); }
  72. }
  73. public void close() { Socket.Close(); }
  74. public void connect(Tuple address)
  75. { try { Socket.Connect(AddressToEndpoint(address)); }
  76. catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
  77. catch(Exception e) { throw new error(e.Message); }
  78. }
  79. public Tuple getpeername()
  80. { try
  81. { IPEndPoint ep = (IPEndPoint)Socket.RemoteEndPoint;
  82. return new Tuple(ep.Address.ToString(), ep.Port);
  83. }
  84. catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
  85. catch(Exception e) { throw new error(e.Message); }
  86. }
  87. public Tuple getsockname()
  88. { try
  89. { IPEndPoint ep = (IPEndPoint)Socket.LocalEndPoint;
  90. return new Tuple(ep.Address.ToString(), ep.Port);
  91. }
  92. catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
  93. catch(Exception e) { throw new error(e.Message); }
  94. }
  95. public object getsockopt(int level, int name)
  96. { try { return Socket.GetSocketOption((SocketOptionLevel)level, (SocketOptionName)name); }
  97. catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
  98. catch(Exception e) { throw new error(e.Message); }
  99. }
  100. public void listen() { listen(5); }
  101. public void listen(int backlog)
  102. { try { Socket.Listen(backlog); }
  103. catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
  104. catch(Exception e) { throw new error(e.Message); }
  105. }
  106. public BoaFile makefile() { return new BoaFile(new NetworkStream(Socket, false)); }
  107. public BoaFile makefile(string mode) { return makefile(); }
  108. public BoaFile makefile(string mode, int bufsize) { return makefile(); }
  109. public byte[] recv(int bufsize) { return recv(bufsize, 0); }
  110. public byte[] recv(int bufsize, int flags)
  111. { try
  112. { byte[] arr = new byte[Math.Min(bufsize, 4096)];
  113. int read = Socket.Receive(arr, (SocketFlags)flags);
  114. if(read==arr.Length) return arr;
  115. byte[] ret = new byte[read];
  116. if(read>0) Array.Copy(arr, ret, read);
  117. return ret;
  118. }
  119. catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
  120. catch(Exception e) { throw new error(e.Message); }
  121. }
  122. public string recvstr(int bufsize) { return recvstr(bufsize, 0); }
  123. public string recvstr(int bufsize, int flags)
  124. { return System.Text.Encoding.Default.GetString(recv(bufsize, flags));
  125. }
  126. public Tuple recvfrom(int bufsize) { return recvfrom(bufsize, 0); }
  127. public Tuple recvfrom(int bufsize, int flags)
  128. { try
  129. { EndPoint ep = new IPEndPoint(IPAddress.Any, 0);
  130. byte[] arr = new byte[Math.Min(bufsize, 4096)];
  131. int read = Socket.ReceiveFrom(arr, (SocketFlags)flags, ref ep);
  132. if(read!=arr.Length)
  133. { byte[] narr = new byte[read];
  134. if(read>0) Array.Copy(arr, narr, read);
  135. arr = narr;
  136. }
  137. IPEndPoint iep = (IPEndPoint)ep;
  138. return new Tuple(arr, new Tuple(iep.Address.ToString(), iep.Port));
  139. }
  140. catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
  141. catch(Exception e) { throw new error(e.Message); }
  142. }
  143. public Tuple recvstrfrom(int bufsize) { return recvstrfrom(bufsize, 0); }
  144. public Tuple recvstrfrom(int bufsize, int flags)
  145. { Tuple tup = recvfrom(bufsize, flags);
  146. tup.items[0] = System.Text.Encoding.Default.GetString((byte[])tup.items[0]);
  147. return tup;
  148. }
  149. public int send(byte[] data) { return send(data, 0); }
  150. public int send(byte[] data, int flags)
  151. { try { return Socket.Send(data, (SocketFlags)flags); }
  152. catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
  153. catch(Exception e) { throw new error(e.Message); }
  154. }
  155. public int send(string str) { return send(str, 0); }
  156. public int send(string str, int flags) { return send(System.Text.Encoding.Default.GetBytes(str), flags); }
  157. public void sendall(byte[] data) { sendall(data, 0); }
  158. public void sendall(byte[] data, int flags)
  159. { try
  160. { int sent=0;
  161. while(sent<data.Length) sent += Socket.Send(data, sent, data.Length-sent, (SocketFlags)flags);
  162. }
  163. catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
  164. catch(Exception e) { throw new error(e.Message); }
  165. }
  166. public void sendall(string str) { sendall(str, 0); }
  167. public void sendall(string str, int flags) { sendall(System.Text.Encoding.Default.GetBytes(str), flags); }
  168. public int sendto(byte[] data, Tuple address) { return sendto(data, 0, address); }
  169. public int sendto(byte[] data, int flags, Tuple address)
  170. { try { return Socket.SendTo(data, (SocketFlags)flags, AddressToEndpoint(address)); }
  171. catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
  172. catch(Exception e) { throw new error(e.Message); }
  173. }
  174. public void setblocking(object value) { Socket.Blocking = Ops.IsTrue(value); }
  175. public void setsockopt(int level, int name, object value)
  176. { try { Socket.SetSocketOption((SocketOptionLevel)level, (SocketOptionName)name, value); }
  177. catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
  178. catch(Exception e) { throw new error(e.Message); }
  179. }
  180. public void shutdown(int how)
  181. { try { Socket.Shutdown((SocketShutdown)how); }
  182. catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
  183. catch(Exception e) { throw new error(e.Message); }
  184. }
  185. public override string ToString() { return "<socket object>"; }
  186. public Socket Socket;
  187. static IPEndPoint AddressToEndpoint(Tuple address)
  188. { IPHostEntry he = Resolve(Ops.ToString(address.__getitem__(0)));
  189. return new IPEndPoint(he.AddressList[0], Ops.ToInt(address.__getitem__(1)));
  190. }
  191. }
  192. #endregion
  193. #region Constants
  194. public const int AF_INET = (int)AddressFamily.InterNetwork;
  195. public const int AF_INET6 = (int)AddressFamily.InterNetworkV6;
  196. public const int AF_UNIX = (int)AddressFamily.Unix;
  197. public const int AF_UNSPEC = (int)AddressFamily.Unspecified;
  198. public const int PF_INET = (int)ProtocolFamily.InterNetwork;
  199. public const int PF_INET6 = (int)ProtocolFamily.InterNetworkV6;
  200. public const int PF_UNIX = (int)ProtocolFamily.Unix;
  201. public const int PF_UNSPEC = (int)ProtocolFamily.Unspecified;
  202. public const int SHUT_RD = (int)SocketShutdown.Receive;
  203. public const int SHUT_WR = (int)SocketShutdown.Send;
  204. public const int SHUT_RDWR = (int)SocketShutdown.Both;
  205. public const int SOCK_STREAM = (int)SocketType.Stream;
  206. public const int SOCK_DGRAM = (int)SocketType.Dgram;
  207. public const int SOCK_RAW = (int)SocketType.Raw;
  208. public const int SOCK_RDM = (int)SocketType.Rdm;
  209. public const int SOCK_SEQPACKET = (int)SocketType.Seqpacket;
  210. public const int MSG_OOB = (int)SocketFlags.OutOfBand;
  211. public const int MSG_PEEK = (int)SocketFlags.Peek;
  212. public const int MSG_DONTROUTE = (int)SocketFlags.DontRoute;
  213. public const int SOL_SOCKET = (int)SocketOptionLevel.Socket;
  214. public const int IPPROTO_ICMP = (int)ProtocolType.Icmp;
  215. public const int IPPROTO_IP = (int)SocketOptionLevel.IP;
  216. public const int IPPROTO_IPV6 = (int)SocketOptionLevel.IPv6;
  217. public const int IPPROTO_RAW = (int)ProtocolType.Raw;
  218. public const int IPPROTO_TCP = (int)SocketOptionLevel.Tcp;
  219. public const int IPPROTO_UDP = (int)SocketOptionLevel.Udp;
  220. public const int SO_BROADCAST = (int)SocketOptionName.Broadcast;
  221. public const int SO_DEBUG = (int)SocketOptionName.Debug;
  222. public const int SO_DONTROUTE = (int)SocketOptionName.DontRoute;
  223. public const int SO_KEEPALIVE = (int)SocketOptionName.KeepAlive;
  224. public const int SO_LINGER = (int)SocketOptionName.Linger;
  225. public const int SO_OOBINLINE = (int)SocketOptionName.OutOfBandInline;
  226. public const int SO_RCVBUF = (int)SocketOptionName.ReceiveBuffer;
  227. public const int SO_REUSEADDR = (int)SocketOptionName.ReuseAddress;
  228. public const int SO_SNDBUF = (int)SocketOptionName.SendBuffer;
  229. public const int TCP_NODELAY = (int)SocketOptionName.NoDelay;
  230. public static readonly bool has_ipv6 = Socket.SupportsIPv6;
  231. #endregion
  232. public static readonly ReflectedType linger = ReflectedType.FromType(typeof(LingerOption));
  233. public static string __repr__() { return "<module 'socket' (built-in)>"; }
  234. public static string __str__() { return __repr__(); }
  235. public static List getaddrinfo(string host, int port)
  236. { return getaddrinfo(host, port, AF_INET, SOCK_STREAM, 0, 0);
  237. }
  238. public static List getaddrinfo(string host, int port, int family)
  239. { return getaddrinfo(host, port, family, SOCK_STREAM, 0, 0);
  240. }
  241. public static List getaddrinfo(string host, int port, int family, int socktype)
  242. { return getaddrinfo(host, port, family, socktype, 0, 0);
  243. }
  244. public static List getaddrinfo(string host, int port, int family, int socktype, int proto)
  245. { return getaddrinfo(host, port, family, socktype, proto, 0);
  246. }
  247. public static List getaddrinfo(string host, int port, int family, int socktype, int proto, int flags)
  248. { IPHostEntry he = Resolve(host);
  249. List list = new List(he.AddressList.Length);
  250. foreach(IPAddress addr in he.AddressList)
  251. list.Add(new Tuple((int)addr.AddressFamily, socktype, proto, he.HostName, new Tuple(addr.ToString(), port)));
  252. return list;
  253. }
  254. public static string getfqdn() { return getfqdn(Dns.GetHostName()); }
  255. public static string getfqdn(string host)
  256. { IPHostEntry he = GetHostByName(host);
  257. if(he.HostName.IndexOf('.')!=-1) return he.HostName;
  258. foreach(string s in he.Aliases) if(s.IndexOf('.')!=-1) return s;
  259. return host;
  260. }
  261. public static Tuple gethostbyaddr(string address) { return HEntryToTuple(GetHostByAddress(address)); }
  262. public static Tuple gethostbyaddr(IPAddress address) { return HEntryToTuple(GetHostByAddress(address)); }
  263. public static string gethostbyname(string host) { return GetHostByName(host).AddressList[0].ToString(); }
  264. public static Tuple gethostbyname_ex(string host) { return HEntryToTuple(GetHostByName(host)); }
  265. public static string gethostname() { return Dns.GetHostName(); }
  266. public static Tuple resolve(string ipOrHost) { return HEntryToTuple(Resolve(ipOrHost)); }
  267. public static int htonl(int i) { return IPAddress.HostToNetworkOrder(i); }
  268. public static short htons(short i) { return IPAddress.HostToNetworkOrder(i); }
  269. public static int ntohl(int i) { return IPAddress.NetworkToHostOrder(i); }
  270. public static short ntohs(short i) { return IPAddress.NetworkToHostOrder(i); }
  271. static IPHostEntry GetHostByAddress(string address)
  272. { try { return Dns.GetHostByAddress(address); }
  273. catch(Exception e) { throw new herror(e.Message); }
  274. }
  275. static IPHostEntry GetHostByAddress(IPAddress address)
  276. { try { return Dns.GetHostByAddress(address); }
  277. catch(Exception e) { throw new herror(e.Message); }
  278. }
  279. static IPHostEntry GetHostByName(string host)
  280. { try { return Dns.GetHostByName(host); }
  281. catch(Exception e) { throw new herror(e.Message); }
  282. }
  283. static Tuple HEntryToTuple(IPHostEntry he)
  284. { List addrs = new List(he.AddressList.Length);
  285. for(int i=0; i<he.AddressList.Length; i++) addrs.Add(he.AddressList[i].ToString());
  286. return new Tuple(he.HostName, new List(he.Aliases), addrs);
  287. }
  288. static IPHostEntry Resolve(string ipOrHost)
  289. { try { return Dns.Resolve(ipOrHost); }
  290. catch(Exception e) { throw new herror(e.Message); }
  291. }
  292. }
  293. } // namespace Boa.Modules