/// <summary> /// Connects to specified host. /// </summary> /// <param name="host">Host name.</param> /// <param name="port">Port number.</param> public void Connect(string host, int port) { if (!m_Connected) { // m_pSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); // IPEndPoint ipdest = new IPEndPoint(System.Net.Dns.Resolve(host).AddressList[0],port); // m_pSocket.Connect(ipdest); Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ipdest = new IPEndPoint(System.Net.Dns.Resolve(host).AddressList[0], port); s.Connect(ipdest); s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 1); m_pSocket = new BufferedSocket(s); // Set connected flag m_Connected = true; string reply = m_pSocket.ReadLine(); if (reply.StartsWith("+OK")) { // Try to read APOP hash key, if supports APOP if (reply.IndexOf("<") > -1 && reply.IndexOf(">") > -1) { m_ApopHashKey = reply.Substring(reply.LastIndexOf("<"), reply.LastIndexOf(">") - reply.LastIndexOf("<") + 1); } } } }
void IEventHelpers.RegisterSocketPeekRead(IEvent e, BufferedSocket socket, IEventHandler protocol, ReadFunction callback) { //Contract.Requires(socket != null); Contract.Requires(protocol != null); Contract.Requires(callback != null); }
/// <summary> /// Connects to IMAP server. /// </summary> /// <param name="host">Host name.</param> /// <param name="port">Port number.</param> public void Connect(string host, int port) { if (!m_Connected) { // m_pSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); // IPEndPoint ipdest = new IPEndPoint(System.Net.Dns.Resolve(host).AddressList[0],port); // m_pSocket.Connect(ipdest); Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ipdest = new IPEndPoint(System.Net.Dns.Resolve(host).AddressList[0], port); s.Connect(ipdest); s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 1); m_pSocket = new BufferedSocket(s); string reply = Core.ReadLine(m_pSocket); reply = reply.Substring(reply.IndexOf(" ")).Trim(); // Remove Cmd tag if (!reply.ToUpper().StartsWith("OK")) { m_pSocket.Close(); m_pSocket = null; throw new Exception("Server returned:" + reply); } m_Connected = true; } }
public void BeginCmd(string sCmd, SocketLineHandler lh) { if (bInUse) { new Exception("IQFeedPort " + portnumber.ToString() + " is in use with '" + sCmd + "'"); } else { this.lh = lh; bInUse = true; iqfport = this; this.sCmd = sCmd; //Monitor.Enter(qPortCmds); lock (qPortCmds.SyncRoot) { if (0 == qPortCmds.Count) { //Console.WriteLine("BeginCmd creating new socket"); bs = new BufferedSocket("127.0.0.1", portnumber, lh); bs.Open(); } else { //Console.WriteLine("BeginCmd regurgitating socket"); bs = qPortCmds.Dequeue() as BufferedSocket; bs.Add(lh); } } //Monitor.Exit(qPortCmds); bs.Send(sCmd); } }
private void Dns_Resolve(IAsyncResult ar) { Random rnd = new Random(); IPHostEntry hostent; ConnQueueItem nextconn = (ConnQueueItem)(ar.AsyncState); while (!ar.IsCompleted) { ar.AsyncWaitHandle.WaitOne(10, false); } try { hostent = Dns.EndGetHostEntry(ar); } catch (Exception e2) { // DNS Failed. BufferedSocket sck = new BufferedSocket(null); sck.sckError = e2; nextconn.cb(sck); return; } nextconn.address = hostent.AddressList[rnd.Next(hostent.AddressList.Length)].ToString(); lock (this) { connectionqueue.Enqueue(nextconn); } }
/// <summary> /// Connects to IMAP server. /// </summary> /// <param name="host">Host name.</param> /// <param name="port">Port number.</param> public void Connect(string host,int port) { if(!m_Connected){ // m_pSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); // IPEndPoint ipdest = new IPEndPoint(System.Net.Dns.Resolve(host).AddressList[0],port); // m_pSocket.Connect(ipdest); Socket s = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); IPEndPoint ipdest = new IPEndPoint(System.Net.Dns.Resolve(host).AddressList[0],port); s.Connect(ipdest); s.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.NoDelay,1); m_pSocket = new BufferedSocket(s); string reply = m_pSocket.ReadLine(); reply = reply.Substring(reply.IndexOf(" ")).Trim(); // Remove Cmd tag if(!reply.ToUpper().StartsWith("OK")){ m_pSocket.Close(); m_pSocket = null; throw new Exception("Server returned:" + reply); } m_Connected = true; } }
public void RegisterSocketWrite(BufferedSocket socket, Action callback) { lock (this) { _onWriteSockets.Add(socket, callback); } }
int IEventHandler.Peek(BufferedSocket bufferedSocket, IByteBuffer msg, ref EndPoint ep) { Contract.Requires(ep != null); //Contract.Requires(bufferedSocket != null); return(default(int)); }
public void RegisterSocketWrite(BufferedSocket socket, Action callback) { #if DEBUG_VERBOSE Console.WriteLine("RegisterSocketWrite"); #endif var handle = (int)socket.Handle; if (handle == -1) { Console.WriteLine("RegisterSocketWrite socket already closed"); return; } if (!AddSocket(handle, EpollEvents.EPOLLOUT)) { } #if DEBUG if (_onWriteSockets.ContainsKey((int)socket.Handle)) { Console.WriteLine("Already waiting on write from socket"); } #endif if (_onWriteSockets.ContainsKey(handle)) { _onWriteSockets[handle] = callback; } else { _onWriteSockets.Add(handle, callback); } }
public void UnregisterSocketWrite(BufferedSocket socket) { lock (this) { _onWriteSockets.Remove(socket); } }
public void UnregisterSocketRead(BufferedSocket socket) { lock (this) { _onReadSockets.Remove(socket); } }
public void UpdateSocketAccept(BufferedSocket socket, Action <BufferedSocket> callback) { var handle = (int)socket.Handle; if (handle == -1) { Console.WriteLine("UpdateSocketAccept socket already closed"); return; } Action acceptHandle = () => { BufferedSocket s2 = null; try { s2 = socket.Accept(); } catch (Exception) { UnregisterSocketAccept(socket); return; } callback(s2); }; if (_onAcceptSockets.ContainsKey(handle)) { _onAcceptSockets[handle] = acceptHandle; } }
public void Open() { bufSock = new BufferedSocket("localhost", 9100, new SocketLineHandler(Handle9100Line)); //bs = new BufferedSocket( "localhost", 9100, hs ); //bs.Add(new Buffer.LineHandler(Handle9100Line)); //hs.bs9100 = bs; // this keeps the reference count up so the object doesn't self-disintegrate bufSock.Open(); }
int IEventHandler.Read(BufferedSocket socket, IByteBuffer msg, ref EndPoint ep) { //Contract.Requires(socket != null); Contract.Requires(msg != null); Contract.Requires(ep != null); return(default(int)); }
public void UnregisterSocketAccept(BufferedSocket socket) { if (!_onAcceptSockets.ContainsKey(socket)) { throw new ArgumentOutOfRangeException("socket", "BufferedSocket does not exist in accept list"); } _onAcceptSockets[socket].Abort(); _onAcceptSockets.Remove(socket); }
private void ConnectToPort5009() { if (null != ConnectingEventHandler) { ConnectingEventHandler(this, EventArgs.Empty); } //smS = stateS.getkey; // may need to use init if we do what we did over in perl bs5009 = new BufferedSocket("localhost", 5009, new SocketLineHandler(ProcessPort5009)); bs5009.Open( ); }
public void Close() { gh = null; instrument = null; bs = null; bars = null; trades = null; quotes = null; stkTrades = null; bufSock.Close(); bufSock = null; }
public void RegisterSocketRead(BufferedSocket socket, Action callback) { lock (this) { #if DEBUG if (_onReadSockets.ContainsKey(socket)) { throw new Exception("Socket already added!"); } #endif _onReadSockets.Add(socket, callback); } }
/// <summary> /// Default constructor. /// </summary> /// <param name="clientSocket">Referance to socket.</param> /// <param name="server">Referance to FTP server.</param> /// <param name="sessionID">Session ID which is assigned to this session.</param> /// <param name="logWriter">Log writer.</param> public FTP_Session(Socket clientSocket, FTP_Server server, string sessionID, _LogWriter logWriter) { m_pSocket = new BufferedSocket(clientSocket); m_pServer = server; m_SessionID = sessionID; m_pLogWriter = logWriter; m_SessionStartTime = DateTime.Now; m_LastDataTime = DateTime.Now; m_pSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 1); // Start session proccessing StartSession(); }
/// <summary> /// Closes connection to POP3 server. /// </summary> public void Disconnect() { if (m_pSocket != null) { // Send QUIT m_pSocket.SendLine("QUIT"); // m_pSocket.Close(); m_pSocket = null; } m_Connected = false; m_Authenticated = false; }
/// <summary> /// Disconnects from IMAP server. /// </summary> public void Disconnect() { if (m_pSocket != null && m_pSocket.Connected) { // Send QUIT Core.SendLine(m_pSocket, "a1 LOGOUT"); // m_pSocket.Close(); m_pSocket = null; } m_Connected = false; m_Authenticated = false; }
public void RegisterSocketRead(IEvent e, BufferedSocket socket, IEventHandler protocol, ReadFunction callback) { e.RegisterSocketRead(socket, () => { EndPoint ep = new IPEndPoint(IPAddress.Any, 0); try { protocol.Read(socket, _msg, ref ep); } catch (SocketException ex) { Console.WriteLine("SocketException occured: " + ex.Message); _msg.Clear(); } callback(_msg, ep); }); }
public void RegisterSocketPeekRead(IEvent e, BufferedSocket socket, IEventHandler protocol, ReadFunction callback) { e.RegisterSocketRead(socket, () => { EndPoint ep = new IPEndPoint(IPAddress.Any, 0); try { protocol.Peek(socket, _msg, ref ep); } catch (SocketException) { _msg.Clear(); } callback(_msg, ep); }); }
public void UnregisterSocket(BufferedSocket socket) { lock (this) { if (_onReadSockets.ContainsKey(socket)) { _onReadSockets.Remove(socket); } if (_onWriteSockets.ContainsKey(socket)) { _onWriteSockets.Remove(socket); } if (_onAcceptSockets.ContainsKey(socket)) { _onAcceptSockets[socket].Abort(); } } }
public void UnregisterSocketAccept(BufferedSocket socket) { #if DEBUG_VERBOSE Console.WriteLine("UnregisterSocketAccept"); #endif var handle = (int)socket.Handle; if (handle == -1) { //if (_onAcceptSockets.ContainsKey(socket.OldHandle)) // _onAcceptSockets.Remove(socket.OldHandle); Console.WriteLine("UnregisterSocketAccept socket already closed"); return; } _onAcceptSockets.Remove(handle); _epoll.Delete(handle); }
public void UnregisterSocketRead(BufferedSocket socket) { #if DEBUG_VERBOSE Console.WriteLine("UnregisterSocketRead"); #endif var handle = (int)socket.Handle; if (handle == -1) { //if (_onReadSockets.ContainsKey(socket.OldHandle)) // _onReadSockets.Remove(socket.OldHandle); Console.WriteLine("UnregisterSocketRead socket already closed"); return; } _onReadSockets.Remove(handle); if (!RemoveSocket(handle, EpollEvents.EPOLLIN)) { } }
public void UnregisterSocket(BufferedSocket socket) { #if DEBUG_VERBOSE Console.WriteLine("UnregisterSocket"); #endif var fd = (int)socket.Handle; if (_onReadSockets.ContainsKey(fd)) { UnregisterSocketRead(socket); } if (_onWriteSockets.ContainsKey(fd)) { UnregisterSocketWrite(socket); } if (_onAcceptSockets.ContainsKey(fd)) { UnregisterSocketAccept(socket); } }
public void RegisterSocketAccept(BufferedSocket socket, Action <BufferedSocket> callback) { var thread = new Thread(() => { try { socket.Socket.Blocking = true; while (socket.IsBound) { BufferedSocket newConnection = socket.Accept(); //newConnection.Blocking = false; lock (this) { Thread.BeginCriticalRegion(); callback(newConnection); Thread.EndCriticalRegion(); } } } catch (ThreadAbortException) { Console.WriteLine("Accept for socket Aborted"); return; } catch (SocketException ex) { if (ex.ErrorCode == 10004) { Console.WriteLine("Accept for socket Aborted"); return; } else { Console.WriteLine("Unknown exception in accept thread: " + ex.Message); } } }); thread.Name = "Socket Accept " + socket.LocalEndPointIp; _onAcceptSockets.Add(socket, thread); thread.Start(); }
/// <summary> /// Ends session, closes socket. /// </summary> private void EndSession() { if (m_pSocket != null) { m_pSocket.Shutdown(SocketShutdown.Both); m_pSocket.Close(); m_pSocket = null; } m_pServer.RemoveSession(this); // Write logs to log file, if needed if (m_pServer.LogCommands) { m_pLogWriter.AddEntry("//----- Sys: 'Session:'" + this.SessionID + " removed " + DateTime.Now); m_pLogWriter.Flush(); } }
/// <summary> /// Connects to specified host. /// </summary> /// <param name="host">Host name.</param> /// <param name="port">Port.</param> public void Connect(string host, int port) { Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ipdest = new IPEndPoint(System.Net.Dns.Resolve(host).AddressList[0], port); s.Connect(ipdest); s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 1); m_pSocket = new BufferedSocket(s); string reply = m_pSocket.ReadLine(); while (!reply.StartsWith("220 ")) { reply = m_pSocket.ReadLine(); } m_Connected = true; }
/// <summary> /// Removes a socket from this thread. Only closed sockets can be removed. Call Disconnect on /// the socket (and wait for sck to be set to null) before attempting to remove it. /// </summary> /// <param name="sck">The closed socket to be removed.</param> public void RemoveSocket(BufferedSocket sck) { if (sockets == null) { throw new ObjectDisposedException("NetworkThread"); } lock (this) { if (sck == null) { throw new ArgumentNullException("sck"); } if (sck.sck != null && sck.sck.Connected) { throw new InvalidOperationException("Cannot remove an active socket. Disconnect the socket first."); } sockets.Remove(sck); } }
/// <summary> /// Disconnects from IMAP server. /// </summary> public void Disconnect() { if(m_pSocket != null && m_pSocket.Connected){ // Send QUIT m_pSocket.SendLine("a1 LOGOUT"); // m_pSocket.Close(); m_pSocket = null; } m_Connected = false; m_Authenticated = false; }
protected void SendToClient(BufferedSocket client, byte[] data) { client.BeginSend(data, 0, data.Length, SocketFlags.None, ClientSendCallback); }
public NetworkEvent(BufferedSocket socket, byte messageId) { MessageId = messageId; Socket = socket; }
/// <summary> /// Removes a socket from this thread. Only closed sockets can be removed. Call Disconnect on /// the socket (and wait for sck to be set to null) before attempting to remove it. /// </summary> /// <param name="sck">The closed socket to be removed.</param> public void RemoveSocket(BufferedSocket sck) { if (sockets == null) throw new ObjectDisposedException("NetworkThread"); lock(this) { if (sck == null) { throw new ArgumentNullException("sck"); } if (sck.sck != null && sck.sck.Connected) { throw new InvalidOperationException("Cannot remove an active socket. Disconnect the socket first."); } sockets.Remove(sck); } }
public NetworkControlEventArgs(BufferedSocket bufSoc, NetworkControlEvent eventId, byte messageId, byte[] data) : base(bufSoc, messageId) { EventId = eventId; Data = data; }
/// <summary> /// Connects to specified host. /// </summary> /// <param name="host">Host name.</param> /// <param name="port">Port.</param> public void Connect(string host,int port) { Socket s = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); IPEndPoint ipdest = new IPEndPoint(System.Net.Dns.Resolve(host).AddressList[0],port); s.Connect(ipdest); s.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.NoDelay,1); m_pSocket = new BufferedSocket(s); string reply = m_pSocket.ReadLine(); while(!reply.StartsWith("220 ")){ reply = m_pSocket.ReadLine(); } m_Connected = true; }
private string m_UserName = ""; // Holds loggedIn UserName. #endregion Fields #region Constructors public SocketServerSession(BufferedSocket socket) { }
private void Dns_Resolve(IAsyncResult ar) { Random rnd = new Random(); IPHostEntry hostent; ConnQueueItem nextconn = (ConnQueueItem)(ar.AsyncState); while (!ar.IsCompleted) ar.AsyncWaitHandle.WaitOne(10, false); try { hostent = Dns.EndGetHostEntry(ar); } catch (Exception e2) { // DNS Failed. BufferedSocket sck = new BufferedSocket(null); sck.sckError = e2; nextconn.cb(sck); return; } nextconn.address = hostent.AddressList[rnd.Next(hostent.AddressList.Length)].ToString(); lock (this) { connectionqueue.Enqueue(nextconn); } }
private void ServerAcceptTcpClient(IAsyncResult ar) { if (!listen) return; // Get the listener that handles the client request. TcpListener listener = (TcpListener)ar.AsyncState; try { Socket client = listener.EndAcceptSocket(ar); Logger.Log("TcpListener", "Accepted client from: " + client.RemoteEndPoint.ToString()); byte[] buffer = new byte[MSG_MAX_LENGTH]; BufferedSocket bufSoc = new BufferedSocket(client, buffer); clients.Add(bufSoc); bufSoc.BeginReceive(bufSoc.ReceiveBuffer, 0, bufSoc.ReceiveBuffer.Length, SocketFlags.None, ClientReceived); } catch (ObjectDisposedException) { Logger.Log("TcpListener", "TcpListener stopped! (stream disposed)"); } // Signal the calling thread to continue. tcpClientConnected.Set(); }
private void SocketThread() { try { // Loop "forever". while(true) { // Even a tiny sleep like this goes a long way to keeping us from using 100% CPU. try { Thread.Sleep(10); } catch (ThreadInterruptedException) {} lock(this) { if ((sockets.Count + connectionqueue.Count) < 1) continue; // Process EXACTLY ONE connection attempt each time through. If we must DNS, // then do so and then put the attempt back on the end. if (connectionqueue.Count > 0) { ConnQueueItem nextconn = connectionqueue.Dequeue(); IPAddress ip; try { ip = IPAddress.Parse(nextconn.address); // We have IP - CONNECT! BufferedSocket sck = new BufferedSocket(new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)); try { sck.sck.Connect(new IPEndPoint(ip, nextconn.port)); // CONNECTED! Notify the callback. nextconn.cb(sck); sockets.Add(sck); } catch (Exception e) { // Connect Failed :( Notify the callback. The callback doesn't need to try to remove - in fact it MUST NOT! I don't know what a double-lock might entail ;) . sck.sck = null; sck.sckError = e; nextconn.cb(sck); } } catch (Exception) { // We must DNS. try { Dns.BeginGetHostEntry(nextconn.address, new AsyncCallback(Dns_Resolve), nextconn); } catch (Exception e2) { // DNS Failed. BufferedSocket sck = new BufferedSocket(null); sck.sckError = e2; nextconn.cb(sck); } } } // Now process Socket buffers. foreach (BufferedSocket sck in sockets) { lock (sck) { // We shouldn't send more than about 1KB at a time, to avoid blocking // in Send(). // If we're pending disconnect... if (sck.sck == null) continue; if (sck.PendingDisconnect) { if (sck.sck.Poll(0, SelectMode.SelectWrite) && sck.sendbuffer.Length > 0) sck.sck.Send(Encoding.ASCII.GetBytes(sck.sendbuffer)); sck.sendbuffer = ""; sck.sck.Shutdown(SocketShutdown.Both); sck.sck.Close(); sck.sck = null; continue; } if (sck.sendbuffer.Length > 0) { byte[] data; if (sck.sendbuffer.Length > 1024) { data = Encoding.ASCII.GetBytes(sck.sendbuffer.Substring(0, 1024)); sck.sendbuffer = sck.sendbuffer.Substring(1024); } else { data = Encoding.ASCII.GetBytes(sck.sendbuffer); sck.sendbuffer = ""; } sck.sck.Send(data); } if (sck.sck.Poll(0, SelectMode.SelectRead) && sck.sck.Available <= 0) { // Remote endpoint disconnected. sck.sendbuffer = ""; if (sck.sck.Poll(0, SelectMode.SelectWrite)) sck.sck.Shutdown(SocketShutdown.Send); sck.sck.Close(); sck.sck = null; } else if (sck.sck.Available > 0) { byte[] data = new byte[sck.sck.Available]; sck.sck.Receive(data); sck.recvbuffer += Encoding.ASCII.GetString(data); } // In case someone had called Monitor.Wait() on this sck, pulse it. Monitor.PulseAll(sck); } } } } } catch (ThreadAbortException) { } }
public void SendToClient(BufferedSocket client, NetworkMessage msg) { byte[] msgData = msg.GetFullMessageBytes(); byte[] length = msgData.Length.ToByteArray(); byte[] completeMsg = new byte[length.Length + msgData.Length]; Array.Copy(length, completeMsg, length.Length); Array.Copy(msgData, 0, completeMsg, length.Length, msgData.Length); SendToClient(client, completeMsg); }
//---- SMTP implementation ----// #region function SendMessageToServer private bool SendMessageToServer(string[] to,string reverse_path,Stream message) { // Get email from to string for(int i=0;i<to.Length;i++){ to[i] = (new InfoControl.Net.Mail.Mime.eAddress(to[i])).Email; } ArrayList defectiveEmails = new ArrayList(); Socket so = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); so.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.SendTimeout,15000); BufferedSocket socket = new BufferedSocket(so); SocketLogger logger = null; if(m_LogCmds && this.SessionLog != null){ logger = new SocketLogger(so,this.SessionLog); logger.SessionID = socket.GetHashCode().ToString(); socket.Logger = logger; } try{ string reply = ""; bool supports_SIZE = false; bool supports_8BIT = false; bool supports_BDAT = false; if(m_UseSmartHost){ socket.Connect(new IPEndPoint(System.Net.Dns.Resolve(m_SmartHost).AddressList[0],m_Port)); } else{ //---- Parse e-domain -------------------------------// string domain = to[0]; // eg. Ivx <*****@*****.**> if(domain.IndexOf("<") > -1 && domain.IndexOf(">") > -1){ domain = domain.Substring(domain.IndexOf("<")+1,domain.IndexOf(">") - domain.IndexOf("<")-1); } if(domain.IndexOf("@") > -1){ domain = domain.Substring(domain.LastIndexOf("@") + 1); } if(domain.Trim().Length == 0){ if(logger != null){ logger.AddTextEntry("Destination address '" + to[0] + "' is invalid, aborting !"); } return false; } //--- Get MX record -------------------------------------------// Dns_Client dns = new Dns_Client(); Dns_Client.DnsServers = m_DnsServers; DnsServerResponse dnsResponse = dns.Query(domain,QTYPE.MX); switch(dnsResponse.ResponseCode) { case RCODE.NO_ERROR: MX_Record[] mxRecords = dnsResponse.GetMXRecords(); // Try all available hosts by MX preference order, if can't connect specified host. foreach(MX_Record mx in mxRecords){ try{ if(logger != null){ logger.AddTextEntry("Connecting with mx record to: " + mx.Host); } socket.Connect(new IPEndPoint(System.Net.Dns.Resolve(mx.Host).AddressList[0],m_Port)); break; } catch{ // Just skip and let for to try next host. if(logger != null){ logger.AddTextEntry("Failed connect to: " + mx.Host); } } } /* Rfc 2821 5 If no MX records are found, but an A RR is found, the A RR is treated as if it was associated with an implicit MX RR, with a preference of 0, pointing to that host. */ if(mxRecords.Length == 0){ // Try to connect with A record IPHostEntry ipEntry = null; try{ if(logger != null){ logger.AddTextEntry("No mx record, trying to get A record for: " + domain); } ipEntry = System.Net.Dns.Resolve(domain); } catch{ if(logger != null){ logger.AddTextEntry("Invalid domain,no MX or A record: " + domain); } OnError(SMTP_ErrorType.InvalidEmailAddress,to,"email domain <" + domain + "> is invalid"); defectiveEmails.AddRange(to); if(logger != null){ logger.Flush(); } return false; } try{ if(logger != null){ logger.AddTextEntry("Connecting with A record to:" + domain); } socket.Connect(new IPEndPoint(ipEntry.AddressList[0],m_Port)); } catch{ if(logger != null){ logger.AddTextEntry("Failed connect to:" + domain); } } } break; case RCODE.NAME_ERROR: if(logger != null){ logger.AddTextEntry("Invalid domain,no MX or A record: " + domain); } OnError(SMTP_ErrorType.InvalidEmailAddress,to,"email domain <" + domain + "> is invalid"); defectiveEmails.AddRange(to); if(logger != null){ logger.Flush(); } return false; case RCODE.SERVER_FAILURE: if(logger != null){ logger.AddTextEntry("Dns server unvailable."); } OnError(SMTP_ErrorType.UnKnown,to,"Dns server unvailable."); defectiveEmails.AddRange(to); if(logger != null){ logger.Flush(); } return false; } } if(!socket.Connected){ OnError(SMTP_ErrorType.UnKnown,to,"Unable connect to server !"); if(logger != null){ logger.Flush(); } return false; } #region Get 220 reply from server /* NOTE: reply may be multiline 220 xx ready or 220-someBull 200 xx */ // Server must reply 220 - Server OK reply = socket.ReadLine(); if(!IsReplyCode("220",reply)){ OnError(SMTP_ErrorType.UnKnown,to,reply); socket.SendLine("QUIT"); if(logger != null){ logger.Flush(); } return false; } else{ // 220-xxx<CRLF> // 220 aa<CRLF> - means end // reply isn't complete, get more while(reply.IndexOf("220 ") == -1){ reply += socket.ReadLine(); } } #endregion #region cmd EHLO/HELO // Send greeting to server socket.SendLine("EHLO " + m_HostName); reply = socket.ReadLine(); if(!IsReplyCode("250",reply)){ // EHLO failed, mayby server doesn't support it, try HELO socket.SendLine("HELO " + m_HostName); reply = socket.ReadLine(); if(!IsReplyCode("250",reply)){ OnError(SMTP_ErrorType.UnKnown,to,reply); socket.SendLine("QUIT"); defectiveEmails.AddRange(to); if(logger != null){ logger.Flush(); } return false; } // else{ // supports_ESMTP = false; // } } else{ // 250-xxx<CRLF> // 250 aa<CRLF> - means end // reply isn't complete, get more while(reply.IndexOf("250 ") == -1){ reply += socket.ReadLine(); } // Check if SIZE argument is supported if(reply.ToUpper().IndexOf("SIZE") > -1){ supports_SIZE = true; } // Check if 8BITMIME argument is supported if(reply.ToUpper().IndexOf("8BITMIME") > -1){ supports_8BIT = true; } // Check if CHUNKING argument is supported if(reply.ToUpper().IndexOf("CHUNKING") > -1){ supports_BDAT = true; } } #endregion //*** All server today support 8-bit, just skip it. // If server doesn't support 8bit mime, check if message is 8bit. // If is we MAY NOT send this message or loss of data /* if(!supports_8BIT){ if(Is8BitMime(message)){ OnError(SMTP_ErrorType.NotSupported,to,"Message is 8-Bit mime and server doesn't support it."); socket.SendLine("QUIT"); if(logger != null){ logger.Flush(); } return false; } }*/ #region cmd AUTH if (this.m_Username != null && m_Username.Length > 0 && m_Password != null && m_Password.Length > 0){ if(reply.ToUpper().IndexOf("AUTH") > -1){ if(reply.ToUpper().IndexOf("LOGIN") > -1){ socket.SendLine("AUTH LOGIN"); reply = socket.ReadLine(); if(!IsReplyCode("334",reply)){ OnError(SMTP_ErrorType.NotAuthenticated,to,"Failed to authenticate"); socket.SendLine("QUIT"); if(logger != null){ logger.Flush(); } return false; } socket.SendLine(Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(m_Username.ToCharArray()))); reply = socket.ReadLine(); if(!IsReplyCode("334",reply)){ OnError(SMTP_ErrorType.NotAuthenticated,to,"Failed to authenticate"); socket.SendLine("QUIT"); if(logger != null){ logger.Flush(); } return false; } socket.SendLine(Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(m_Password.ToCharArray()))); reply = socket.ReadLine(); if(!IsReplyCode("235",reply)){ OnError(SMTP_ErrorType.NotAuthenticated,to,"Failed to authenticate"); socket.SendLine("QUIT"); if(logger != null){ logger.Flush(); } return false; } } // if(reply.ToUpper().IndexOf("CRAM-MD5") > -1) // { // socket.SendLine("AUTH CRAM-MD5"); // reply = socket.ReadLine(); // if (IsReplyCode("334",auth)) // { // socket.SendLine(Convert.ToBase64String(Encoding.ASCII.GetBytes(m_Username.ToCharArray()))); // socket.SendLine(Convert.ToBase64String(Encoding.ASCII.GetBytes(m_Password.ToCharArray()))); // } // } } else{ //server did not support AUTH } } #endregion #region cmd MAIL // NOTE: Syntax:{MAIL FROM:<*****@*****.**> [SIZE=msgSize]<CRLF>} // Send Mail From if(supports_SIZE){ socket.SendLine("MAIL FROM:<" + reverse_path + "> SIZE=" + (message.Length - message.Position)); } else{ socket.SendLine("MAIL FROM:<" + reverse_path + ">"); } reply = socket.ReadLine(); if(!IsReplyCode("250",reply)){ // To Do: Check if size exceeded error: OnError(SMTP_ErrorType.UnKnown,to,reply); socket.SendLine("QUIT"); defectiveEmails.AddRange(to); if(logger != null){ logger.Flush(); } return false; } #endregion #region cmd RCPT // NOTE: Syntax:{RCPT TO:<*****@*****.**><CRLF>} bool isAnyValidEmail = false; foreach(string rcpt in to){ // Send Mail To socket.SendLine("RCPT TO:<" + rcpt + ">"); reply = socket.ReadLine(); if(!IsReplyCode("250",reply)){ // Is unknown user if(IsReplyCode("550",reply)){ OnError(SMTP_ErrorType.InvalidEmailAddress,new string[]{rcpt},reply); } else{ OnError(SMTP_ErrorType.UnKnown,new string[]{rcpt},reply); } defectiveEmails.Add(rcpt); } else{ isAnyValidEmail = true; } } // If there isn't any valid email - quit. if(!isAnyValidEmail){ socket.SendLine("QUIT"); if(logger != null){ logger.Flush(); } return false; } //---------------------------------------------// #endregion #region cmd DATA if(!(supports_BDAT && m_UseBDAT)){ // Notify Data Start socket.SendLine("DATA"); reply = socket.ReadLine(); if(!IsReplyCode("354",reply)){ OnError(SMTP_ErrorType.UnKnown,to,reply); socket.SendLine("QUIT"); defectiveEmails.AddRange(to); if(logger != null){ logger.Flush(); } return false; } //------- Do period handling -----------------------------------------// // If line starts with '.', add additional '.'.(Read rfc for more info) MemoryStream msgStrmPeriodOk = Core.DoPeriodHandling(message,true,false); //--------------------------------------------------------------------// // Check if message ends with <CRLF>, if not add it. -------// if(msgStrmPeriodOk.Length >= 2){ byte[] byteEnd = new byte[2]; msgStrmPeriodOk.Position = msgStrmPeriodOk.Length - 2; msgStrmPeriodOk.Read(byteEnd,0,2); if(byteEnd[0] != (byte)'\r' && byteEnd[1] != (byte)'\n'){ msgStrmPeriodOk.Write(new byte[]{(byte)'\r',(byte)'\n'},0,2); } } msgStrmPeriodOk.Position = 0; //-----------------------------------------------------------// //---- Send message --------------------------------------------// long totalSent = 0; long totalLength = msgStrmPeriodOk.Length; while(totalSent < totalLength){ byte[] dataBuf = new byte[4000]; int nCount = msgStrmPeriodOk.Read(dataBuf,0,dataBuf.Length); int countSended = socket.Send(dataBuf,0,nCount,SocketFlags.None); totalSent += countSended; if(countSended != nCount){ msgStrmPeriodOk.Position = totalSent; } OnPartOfMessageIsSent(countSended,totalSent,totalLength); } //-------------------------------------------------------------// msgStrmPeriodOk.Close(); // Notify End of Data socket.SendLine("."); reply = socket.ReadLine(); if(!IsReplyCode("250",reply)){ OnError(SMTP_ErrorType.UnKnown,to,reply); socket.SendLine("QUIT"); defectiveEmails.AddRange(to); if(logger != null){ logger.Flush(); } return false; } } #endregion #region cmd BDAT if(supports_BDAT && m_UseBDAT){ socket.SendLine("BDAT " + (message.Length - message.Position) + " LAST"); //---- Send message --------------------------------------------// long totalSent = 0; long totalLength = message.Length - message.Position; while(totalSent < totalLength){ byte[] dataBuf = new byte[4000]; int nCount = message.Read(dataBuf,0,dataBuf.Length); int countSended = socket.Send(dataBuf,0,nCount,SocketFlags.None); totalSent += countSended; if(countSended != nCount){ message.Position = totalSent; } OnPartOfMessageIsSent(countSended,totalSent,totalLength); } //-------------------------------------------------------------// // Get store result reply = socket.ReadLine(); if(!reply.StartsWith("250")){ OnError(SMTP_ErrorType.UnKnown,to,reply); socket.SendLine("QUIT"); defectiveEmails.AddRange(to); if(logger != null){ logger.Flush(); } return false; } } #endregion #region cmd QUIT // Notify server - server can exit now socket.SendLine("QUIT"); // reply = socket.ReadLine(); #endregion } catch(Exception x){ OnError(SMTP_ErrorType.UnKnown,to,x.Message); defectiveEmails.AddRange(to); if(logger != null){ logger.Flush(); } return false; } finally{ // Raise event OnSendJobCompleted(Thread.CurrentThread.GetHashCode().ToString(),to,defectiveEmails); } if(logger != null){ logger.Flush(); } return true; }