boaold /Backend/Modules/_socket.cs

Language C# Lines 355
MD5 Hash 7cdf7f0d1268d133ed86213c47d37952 Estimated Cost $6,939 (why?)
Repository https://bitbucket.org/AdamMil/boaold View Raw File View Project SPDX
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
/*
Boa is the reference implementation for a language similar to Python,
also called Boa. This implementation is both interpreted and compiled,
targeting the Microsoft .NET Framework.

http://www.adammil.net/
Copyright (C) 2004-2005 Adam Milazzo

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

using System;
using System.Net;
using System.Net.Sockets;
using Boa.Runtime;

namespace Boa.Modules
{

[BoaType("module")]
public sealed class _socket
{ _socket() { }

  #region Support classes
  public class error : RuntimeException
  { public error(int code, string message) : base(message) { this.code=code; }
    public error(string message) : base(message) { }

    public int code;
  }
  
  public class herror : error
  { public herror(int code, string message) : base(code, message) { }
    public herror(string message) : base(message) { }
  }
  
  public class gaierror : error
  { public gaierror(int code, string message) : base(code, message) { }
    public gaierror(string message) : base(message) { }
  }

  public class timeout : error
  { public timeout() : base("timed out") { }
  }

  // TODO: support IPv6 addresses
  public class socket
  { public socket() : this(AF_INET, SOCK_STREAM, 0) { }
    public socket(int family) : this(family, SOCK_STREAM, 0) { }
    public socket(int family, int type) : this(family, type, 0) { }
    public socket(int family, int type, int proto) :
      this((AddressFamily)family, (SocketType)type, (ProtocolType)proto) { }
    public socket(AddressFamily family, SocketType type, ProtocolType proto)
    { try { Socket = new Socket(family, type, proto); }
      catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
      catch(Exception e) { throw new error(e.Message); }
    }

    public socket(Socket socket) { Socket=socket; }

    public bool connected { get { return Socket.Connected; } }
    public int waiting { get { return Socket.Available; } }

    public Tuple accept()
    { try
      { socket s = new socket(Socket.Accept());
        return new Tuple(s, s.getpeername());
      }
      catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
      catch(Exception e) { throw new error(e.Message); }
    }
    
    public void bind(Tuple address)
    { try { Socket.Bind(AddressToEndpoint(address)); }
      catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
      catch(Exception e) { throw new error(e.Message); }
    }
    
    public void close() { Socket.Close(); }

    public void connect(Tuple address)
    { try { Socket.Connect(AddressToEndpoint(address)); }
      catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
      catch(Exception e) { throw new error(e.Message); }
    }

    public Tuple getpeername()
    { try
      { IPEndPoint ep = (IPEndPoint)Socket.RemoteEndPoint;
        return new Tuple(ep.Address.ToString(), ep.Port);
      }
      catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
      catch(Exception e) { throw new error(e.Message); }
    }
    
    public Tuple getsockname()
    { try
      { IPEndPoint ep = (IPEndPoint)Socket.LocalEndPoint;
        return new Tuple(ep.Address.ToString(), ep.Port);
      }
      catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
      catch(Exception e) { throw new error(e.Message); }
    }

    public object getsockopt(int level, int name)
    { try { return Socket.GetSocketOption((SocketOptionLevel)level, (SocketOptionName)name); }
      catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
      catch(Exception e) { throw new error(e.Message); }
    }

    public void listen() { listen(5); }
    public void listen(int backlog)
    { try { Socket.Listen(backlog); }
      catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
      catch(Exception e) { throw new error(e.Message); }
    }

    public BoaFile makefile() { return new BoaFile(new NetworkStream(Socket, false)); }
    public BoaFile makefile(string mode) { return makefile(); }
    public BoaFile makefile(string mode, int bufsize) { return makefile(); }

    public byte[] recv(int bufsize) { return recv(bufsize, 0); }
    public byte[] recv(int bufsize, int flags)
    { try
      { byte[] arr = new byte[Math.Min(bufsize, 4096)];
        int read = Socket.Receive(arr, (SocketFlags)flags);
        if(read==arr.Length) return arr;
        byte[] ret = new byte[read];
        if(read>0) Array.Copy(arr, ret, read);
        return ret;
      }
      catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
      catch(Exception e) { throw new error(e.Message); }
    }

    public string recvstr(int bufsize) { return recvstr(bufsize, 0); }
    public string recvstr(int bufsize, int flags)
    { return System.Text.Encoding.Default.GetString(recv(bufsize, flags));
    }

    public Tuple recvfrom(int bufsize) { return recvfrom(bufsize, 0); }
    public Tuple recvfrom(int bufsize, int flags)
    { try
      { EndPoint ep = new IPEndPoint(IPAddress.Any, 0);
        byte[] arr = new byte[Math.Min(bufsize, 4096)];
        int read = Socket.ReceiveFrom(arr, (SocketFlags)flags, ref ep);
        if(read!=arr.Length)
        { byte[] narr = new byte[read];
          if(read>0) Array.Copy(arr, narr, read);
          arr = narr;
        }
        IPEndPoint iep = (IPEndPoint)ep;
        return new Tuple(arr, new Tuple(iep.Address.ToString(), iep.Port));
      }
      catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
      catch(Exception e) { throw new error(e.Message); }
    }

    public Tuple recvstrfrom(int bufsize) { return recvstrfrom(bufsize, 0); }
    public Tuple recvstrfrom(int bufsize, int flags)
    { Tuple tup = recvfrom(bufsize, flags);
      tup.items[0] = System.Text.Encoding.Default.GetString((byte[])tup.items[0]);
      return tup;
    }

    public int send(byte[] data) { return send(data, 0); }
    public int send(byte[] data, int flags)
    { try { return Socket.Send(data, (SocketFlags)flags); }
      catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
      catch(Exception e) { throw new error(e.Message); }
    }

    public int send(string str) { return send(str, 0); }
    public int send(string str, int flags) { return send(System.Text.Encoding.Default.GetBytes(str), flags); }

    public void sendall(byte[] data) { sendall(data, 0); }
    public void sendall(byte[] data, int flags)
    { try
      { int sent=0;
        while(sent<data.Length) sent += Socket.Send(data, sent, data.Length-sent, (SocketFlags)flags);
      }
      catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
      catch(Exception e) { throw new error(e.Message); }
    }

    public void sendall(string str) { sendall(str, 0); }
    public void sendall(string str, int flags) { sendall(System.Text.Encoding.Default.GetBytes(str), flags); }

    public int sendto(byte[] data, Tuple address) { return sendto(data, 0, address); }
    public int sendto(byte[] data, int flags, Tuple address)
    { try { return Socket.SendTo(data, (SocketFlags)flags, AddressToEndpoint(address)); }
      catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
      catch(Exception e) { throw new error(e.Message); }
    }
    
    public void setblocking(object value) { Socket.Blocking = Ops.IsTrue(value); }

    public void setsockopt(int level, int name, object value)
    { try { Socket.SetSocketOption((SocketOptionLevel)level, (SocketOptionName)name, value); }
      catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
      catch(Exception e) { throw new error(e.Message); }
    }

    public void shutdown(int how)
    { try { Socket.Shutdown((SocketShutdown)how); }
      catch(SocketException e) { throw new error(e.ErrorCode, e.Message); }
      catch(Exception e) { throw new error(e.Message); }
    }
    
    public override string ToString() { return "<socket object>"; }

    public Socket Socket;
    
    static IPEndPoint AddressToEndpoint(Tuple address)
    { IPHostEntry he = Resolve(Ops.ToString(address.__getitem__(0)));
      return new IPEndPoint(he.AddressList[0], Ops.ToInt(address.__getitem__(1)));
    }
  }
  #endregion

  #region Constants
  public const int AF_INET   = (int)AddressFamily.InterNetwork;
  public const int AF_INET6  = (int)AddressFamily.InterNetworkV6;
  public const int AF_UNIX   = (int)AddressFamily.Unix;
  public const int AF_UNSPEC = (int)AddressFamily.Unspecified;
  
  public const int PF_INET   = (int)ProtocolFamily.InterNetwork;
  public const int PF_INET6  = (int)ProtocolFamily.InterNetworkV6;
  public const int PF_UNIX   = (int)ProtocolFamily.Unix;
  public const int PF_UNSPEC = (int)ProtocolFamily.Unspecified;
  
  public const int SHUT_RD   = (int)SocketShutdown.Receive;
  public const int SHUT_WR   = (int)SocketShutdown.Send;
  public const int SHUT_RDWR = (int)SocketShutdown.Both;

  public const int SOCK_STREAM = (int)SocketType.Stream;
  public const int SOCK_DGRAM  = (int)SocketType.Dgram;
  public const int SOCK_RAW    = (int)SocketType.Raw;
  public const int SOCK_RDM    = (int)SocketType.Rdm;
  public const int SOCK_SEQPACKET = (int)SocketType.Seqpacket;

  public const int MSG_OOB = (int)SocketFlags.OutOfBand;
  public const int MSG_PEEK = (int)SocketFlags.Peek;
  public const int MSG_DONTROUTE = (int)SocketFlags.DontRoute;

  public const int SOL_SOCKET   = (int)SocketOptionLevel.Socket;
  public const int IPPROTO_ICMP = (int)ProtocolType.Icmp;
  public const int IPPROTO_IP   = (int)SocketOptionLevel.IP;
  public const int IPPROTO_IPV6 = (int)SocketOptionLevel.IPv6;
  public const int IPPROTO_RAW  = (int)ProtocolType.Raw;
  public const int IPPROTO_TCP  = (int)SocketOptionLevel.Tcp;
  public const int IPPROTO_UDP  = (int)SocketOptionLevel.Udp;

  public const int SO_BROADCAST = (int)SocketOptionName.Broadcast;
  public const int SO_DEBUG = (int)SocketOptionName.Debug;
  public const int SO_DONTROUTE = (int)SocketOptionName.DontRoute;
  public const int SO_KEEPALIVE = (int)SocketOptionName.KeepAlive;
  public const int SO_LINGER = (int)SocketOptionName.Linger;
  public const int SO_OOBINLINE = (int)SocketOptionName.OutOfBandInline;
  public const int SO_RCVBUF = (int)SocketOptionName.ReceiveBuffer;
  public const int SO_REUSEADDR = (int)SocketOptionName.ReuseAddress;
  public const int SO_SNDBUF = (int)SocketOptionName.SendBuffer;

  public const int TCP_NODELAY = (int)SocketOptionName.NoDelay;
  
  public static readonly bool has_ipv6 = Socket.SupportsIPv6;
  #endregion
  
  public static readonly ReflectedType linger = ReflectedType.FromType(typeof(LingerOption));

  public static string __repr__() { return "<module 'socket' (built-in)>"; }
  public static string __str__() { return __repr__(); }
  
  public static List getaddrinfo(string host, int port)
  { return getaddrinfo(host, port, AF_INET, SOCK_STREAM, 0, 0);
  }
  public static List getaddrinfo(string host, int port, int family)
  { return getaddrinfo(host, port, family, SOCK_STREAM, 0, 0);
  }
  public static List getaddrinfo(string host, int port, int family, int socktype)
  { return getaddrinfo(host, port, family, socktype, 0, 0);
  }
  public static List getaddrinfo(string host, int port, int family, int socktype, int proto)
  { return getaddrinfo(host, port, family, socktype, proto, 0);
  }
  public static List getaddrinfo(string host, int port, int family, int socktype, int proto, int flags)
  { IPHostEntry he = Resolve(host);
    List list = new List(he.AddressList.Length);
    foreach(IPAddress addr in he.AddressList)
      list.Add(new Tuple((int)addr.AddressFamily, socktype, proto, he.HostName, new Tuple(addr.ToString(), port)));
    return list;
  }

  public static string getfqdn() { return getfqdn(Dns.GetHostName()); }
  public static string getfqdn(string host)
  { IPHostEntry he = GetHostByName(host);
    if(he.HostName.IndexOf('.')!=-1) return he.HostName;
    foreach(string s in he.Aliases) if(s.IndexOf('.')!=-1) return s;
    return host;
  }

  public static Tuple gethostbyaddr(string address) { return HEntryToTuple(GetHostByAddress(address)); }
  public static Tuple gethostbyaddr(IPAddress address) { return HEntryToTuple(GetHostByAddress(address)); }
  
  public static string gethostbyname(string host) { return GetHostByName(host).AddressList[0].ToString(); }
  public static Tuple gethostbyname_ex(string host) { return HEntryToTuple(GetHostByName(host)); }

  public static string gethostname() { return Dns.GetHostName(); }

  public static Tuple resolve(string ipOrHost) { return HEntryToTuple(Resolve(ipOrHost)); }

  public static int htonl(int i) { return IPAddress.HostToNetworkOrder(i); }
  public static short htons(short i) { return IPAddress.HostToNetworkOrder(i); }
  public static int ntohl(int i) { return IPAddress.NetworkToHostOrder(i); }
  public static short ntohs(short i) { return IPAddress.NetworkToHostOrder(i); }

  static IPHostEntry GetHostByAddress(string address)
  { try { return Dns.GetHostByAddress(address); }
    catch(Exception e) { throw new herror(e.Message); }
  }

  static IPHostEntry GetHostByAddress(IPAddress address)
  { try { return Dns.GetHostByAddress(address); }
    catch(Exception e) { throw new herror(e.Message); }
  }

  static IPHostEntry GetHostByName(string host)
  { try { return Dns.GetHostByName(host); }
    catch(Exception e) { throw new herror(e.Message); }
  }

  static Tuple HEntryToTuple(IPHostEntry he)
  { List addrs = new List(he.AddressList.Length);
    for(int i=0; i<he.AddressList.Length; i++) addrs.Add(he.AddressList[i].ToString());
    return new Tuple(he.HostName, new List(he.Aliases), addrs);
  }

  static IPHostEntry Resolve(string ipOrHost)
  { try { return Dns.Resolve(ipOrHost); }
    catch(Exception e) { throw new herror(e.Message); }
  }
}

} // namespace Boa.Modules
Back to Top