public override void Start() { if (FileTransfer.FileTransferDirection == FileTransferDirection.Send) { /// Tell the other end we want to send a file.. give them a list of SOCKS5 servers they can connect to (hopefully our open fire server supports it) /// IQStart = new ByteStreamQueryIQ(); //IQStart.SID = this.FileTransfer.sid; IQStart.ByteStreamQuery = new ByteStreamQuery(); IQStart.ByteStreamQuery.SID = this.FileTransfer.sid; IQStart.ByteStreamQuery.Mode = StreamMode.tcp.ToString(); IQStart.From = XMPPClient.JID; IQStart.To = FileTransfer.RemoteJID; IQStart.Type = IQType.set.ToString(); /// Build our stream objects /// /// For windows we can start a local listener and a proxy listener /// For windows phone we can only use the proxy (if our jabber server supports it) because we can't listen for connections /// string strJID = string.Format("proxy.{0}", XMPPClient.Domain); string strHost = XMPPClient.Server; string strPort = "7777"; if ((FileTransferManager.SOCKS5Proxy != null) && (FileTransferManager.SOCKS5Proxy.Length > 0)) { /// User supplied socks5 proxy...TODO, add port configuration strJID = FileTransferManager.SOCKS5Proxy; strHost = FileTransferManager.SOCKS5Proxy; strPort = "7777"; } else { /// Query our xmpp server for a proxy, then for the details /// item filetransfer = FindProxyItem(); if (filetransfer != null) { strJID = filetransfer.JID; /// Query the server for the actual stream host of thi sitem ByteStreamQueryIQ iqqueryproxy = new ByteStreamQueryIQ(); iqqueryproxy.From = XMPPClient.JID; iqqueryproxy.To = strJID; iqqueryproxy.Type = IQType.get.ToString(); iqqueryproxy.ByteStreamQuery = new ByteStreamQuery(); IQ iqret = XMPPClient.SendRecieveIQ(iqqueryproxy, 15000, SerializationMethod.XMLSerializeObject); if ((iqret != null) && (iqret is ByteStreamQueryIQ)) { ByteStreamQueryIQ response = iqret as ByteStreamQueryIQ; if ((response.ByteStreamQuery != null) && (response.ByteStreamQuery.Hosts != null) && (response.ByteStreamQuery.Hosts.Length > 0)) { strHost = response.ByteStreamQuery.Hosts[0].Host; strPort = response.ByteStreamQuery.Hosts[0].Port; strJID = response.ByteStreamQuery.Hosts[0].Jid; } } } } StreamHost host = new StreamHost() { Host = strHost, Port = strPort, Jid = strJID }; //StreamHost host = new StreamHost() { Host = "192.168.1.124", Port = "7777", Jid = string.Format("proxy.{0}", XMPPClient.Domain) }; IQStart.ByteStreamQuery.Hosts = new StreamHost[] { host }; IQStart.ByteStreamQuery.Mode = StreamMode.tcp.ToString(); XMPPClient.SendObject(IQStart); } else { } base.Start(); }
public void SendFileThread(object obj) { ByteStreamQueryIQ bsiq = obj as ByteStreamQueryIQ; /// Attempt to open our hosts /// StreamHost host = bsiq.ByteStreamQuery.StreamHostUsed; SocketServer.SocketClient client = new SocketClient(); client.SetSOCKSProxy(5, XMPPClient.Server, 7777, "xmppclient"); client.OnAsyncConnectFinished += new DelegateConnectFinish(client_OnAsyncConnectFinished); EventConnected.Reset(); ConnectSuccesful = false; string strHost = string.Format("{0}{1}{2}", this.FileTransfer.sid, XMPPClient.JID, bsiq.From); System.Security.Cryptography.SHA1Managed sha = new System.Security.Cryptography.SHA1Managed(); byte [] bBytes = sha.ComputeHash(System.Text.UTF8Encoding.UTF8.GetBytes(strHost)); strHost = SocketServer.TLS.ByteHelper.HexStringFromByte(bBytes, false, int.MaxValue).ToLower(); /// Connect parametrs are the sha1 hash and 0, the socks proxy will connect us to the correct place client.ConnectAsync(strHost, 0); EventConnected.WaitOne(); if (ConnectSuccesful == true) { /// Now we must activate the proxy so we can send /// EventActivate.Reset(); IQActivate = new ByteStreamQueryIQ(); IQActivate.ByteStreamQuery = new ByteStreamQuery(); IQActivate.ByteStreamQuery.SID = this.FileTransfer.sid; IQActivate.From = XMPPClient.JID; IQActivate.To = host.Jid; IQActivate.Type = IQType.set.ToString(); IQActivate.ByteStreamQuery.Activate = FileTransfer.RemoteJID; XMPPClient.SendObject(IQActivate); EventActivate.WaitOne(); if (IsCompleted == true) { /// Error, exit this thread FileTransfer.FileTransferState = FileTransferState.Error; XMPPClient.FileTransferManager.FinishActiveFileTransfer(FileTransfer); return; } FileTransfer.BytesRemaining = FileTransfer.Bytes.Length; FileTransfer.FileTransferState = FileTransferState.Transferring; /// Now send all our data /// ByteBuffer buffer = new ByteBuffer(); buffer.AppendData(FileTransfer.Bytes); while (buffer.Size > 0) { int nSize = (buffer.Size > 16384) ? 16384 : buffer.Size; Sockets.SocketAsyncEventArgs asyncsend = new Sockets.SocketAsyncEventArgs(); asyncsend.SetBuffer(buffer.GetNSamples(nSize), 0, nSize); asyncsend.Completed += new EventHandler<Sockets.SocketAsyncEventArgs>(asyncsend_Completed); SendCompletedEvent.Reset(); bSendSuccess = false; bool bSent = false; try { client.socket.SendAsync(asyncsend); } catch (Exception ex) { IsCompleted = true; FileTransfer.Error = ex.Message; FileTransfer.FileTransferState = FileTransferState.Error; return; } SendCompletedEvent.WaitOne(); if (IsCompleted == true) break; if ((bSendSuccess == false) && (bSent == false) ) /// was sent async because bSent is false, so we can examine bSendSuccess to make sure we sent the right number of bytes { break; } FileTransfer.BytesRemaining -= nSize; } client.Disconnect(); FileTransfer.FileTransferState = FileTransferState.Done; IsCompleted = true; XMPPClient.FileTransferManager.FinishActiveFileTransfer(FileTransfer); return; } FileTransfer.Error = "Failed to send data"; FileTransfer.FileTransferState = FileTransferState.Error; IsCompleted = true; }
public void DownloadThread(object obj) { ByteStreamQueryIQ bsiq = obj as ByteStreamQueryIQ; /// Attempt to open our hosts /// foreach (StreamHost host in bsiq.ByteStreamQuery.Hosts) { if (IsCompleted == true) break; SocketServer.SocketClient client = new SocketClient(); client.SetSOCKSProxy(5, host.Host, Convert.ToInt32(host.Port), "xmppclient"); client.OnAsyncConnectFinished += new DelegateConnectFinish(client_OnAsyncConnectFinished); EventConnected.Reset(); ConnectSuccesful = false; string strHost = string.Format("{0}{1}{2}", this.FileTransfer.sid, bsiq.From, bsiq.To); System.Security.Cryptography.SHA1Managed sha = new System.Security.Cryptography.SHA1Managed(); byte [] bBytes = sha.ComputeHash(System.Text.UTF8Encoding.UTF8.GetBytes(strHost)); strHost = SocketServer.TLS.ByteHelper.HexStringFromByte(bBytes, false, int.MaxValue).ToLower(); /// Connect parametrs are the sha1 hash and 0, the socks proxy will connect us to the correct place client.StartReadOnConnect = true; client.ConnectAsync(strHost, 0); EventConnected.WaitOne(); if (ConnectSuccesful == true) { FileTransfer.FileTransferState = FileTransferState.Transferring; client.OnReceiveMessage += new SocketClient.SocketReceiveHandler(client_OnReceiveMessage); DownloadFileBuffer.GetAllSamples(); /// connected and negotiated socks5, tell the far end to start sending data /// ByteStreamQueryIQ iqresponse = new ByteStreamQueryIQ(); iqresponse.SID = this.FileTransfer.sid; iqresponse.ByteStreamQuery = new ByteStreamQuery(); iqresponse.ByteStreamQuery.StreamHostUsed = new StreamHost(); iqresponse.ByteStreamQuery.StreamHostUsed.Jid = host.Jid; iqresponse.From = XMPPClient.JID; iqresponse.ID = bsiq.ID; iqresponse.To = bsiq.From; iqresponse.Type = IQType.result.ToString(); XMPPClient.SendObject(iqresponse); /// Now read data until we get our desired amount /// EventGotAllData.WaitOne(); client.Disconnect(); return; } } /// Couldn't transfer file, send error /// ByteStreamQueryIQ response = new ByteStreamQueryIQ(); response.ByteStreamQuery = bsiq.ByteStreamQuery; response.From = XMPPClient.JID; response.To = bsiq.From; response.ID = bsiq.ID; response.Type = IQType.error.ToString(); response.Error = new Error(ErrorType.remoteservertimeout); XMPPClient.SendXMPP(response); FileTransfer.Error = "Could not connect to proxy"; FileTransfer.FileTransferState = FileTransferState.Error; XMPPClient.FileTransferManager.FinishActiveFileTransfer(FileTransfer); }
public override bool NewIQ(IQ iq) { if (this.IsCompleted == true) // We've been cancelled return false; if (FileTransfer.FileTransferDirection == FileTransferDirection.Send) { if ( (IQStart != null) && (iq.ID == IQStart.ID) ) { if (iq.Type == IQType.error.ToString()) { IsCompleted = true; if (iq.Error != null) FileTransfer.Error = iq.Error.ErrorDescription; FileTransfer.FileTransferState = FileTransferState.Error; XMPPClient.FileTransferManager.FinishActiveFileTransfer(FileTransfer); } else if (iq is ByteStreamQueryIQ) { ByteStreamQueryIQ bsiq = iq as ByteStreamQueryIQ; if (bsiq.Type == IQType.result.ToString()) { System.Threading.ThreadPool.QueueUserWorkItem(new Threading.WaitCallback(SendFileThread), bsiq); } else if (bsiq.Type == IQType.error.ToString()) { IsCompleted = true; if (iq.Error != null) FileTransfer.Error = bsiq.Error.ErrorDescription; FileTransfer.FileTransferState = FileTransferState.Error; } } return true; } if ((IQActivate != null) && (iq.ID == IQActivate.ID)) { EventActivate.Set(); return true; } } else { if (iq is ByteStreamQueryIQ) { ByteStreamQueryIQ bsiq = iq as ByteStreamQueryIQ; if ( (bsiq.ByteStreamQuery != null) && (bsiq.ByteStreamQuery.Hosts != null) && (bsiq.ByteStreamQuery.Hosts.Length > 0) ) { System.Threading.ThreadPool.QueueUserWorkItem(new Threading.WaitCallback(DownloadThread), bsiq); } else { ByteStreamQueryIQ response = new ByteStreamQueryIQ(); response.ByteStreamQuery = bsiq.ByteStreamQuery; response.From = XMPPClient.JID; response.To = bsiq.From; response.ID = bsiq.ID; response.Type = IQType.error.ToString(); response.Error = new Error(ErrorType.notacceptable); XMPPClient.SendXMPP(response); } /// See qh /// return true; } } return false; }
public override void Start() { if (FileTransfer.FileTransferDirection == FileTransferDirection.Send) { /// Tell the other end we want to send a file.. give them a list of SOCKS5 servers they can connect to (hopefully our open fire server supports it) /// IQStart = new ByteStreamQueryIQ(); //IQStart.SID = this.FileTransfer.sid; IQStart.ByteStreamQuery = new ByteStreamQuery(); IQStart.ByteStreamQuery.SID = this.FileTransfer.sid; IQStart.ByteStreamQuery.Mode = StreamMode.tcp.ToString(); IQStart.From = XMPPClient.JID; IQStart.To = FileTransfer.RemoteJID; IQStart.Type = IQType.set.ToString(); /// Build our stream objects /// /// For windows we can start a local listener and a proxy listener /// For windows phone we can only use the proxy (if our jabber server supports it) because we can't listen for connections /// string strJID = string.Format("proxy.{0}", XMPPClient.Domain); string strHost = XMPPClient.Server; string strPort = "7777"; if ((FileTransferManager.SOCKS5Proxy != null) && (FileTransferManager.SOCKS5Proxy.Length > 0)) { /// User supplied socks5 proxy...TODO, add port configuration strJID = FileTransferManager.SOCKS5Proxy; strHost = FileTransferManager.SOCKS5Proxy; strPort = "7777"; } else { /// Query our xmpp server for a proxy, then for the details /// item filetransfer = FindProxyItem(); if (filetransfer != null) { strJID = filetransfer.JID; /// Query the server for the actual stream host of thi sitem ByteStreamQueryIQ iqqueryproxy = new ByteStreamQueryIQ(); iqqueryproxy.From = XMPPClient.JID; iqqueryproxy.To = strJID; iqqueryproxy.Type = IQType.get.ToString(); iqqueryproxy.ByteStreamQuery = new ByteStreamQuery(); IQ iqret = XMPPClient.SendRecieveIQ(iqqueryproxy, 15000, SerializationMethod.XMLSerializeObject); if ((iqret != null) && (iqret is ByteStreamQueryIQ)) { ByteStreamQueryIQ response = iqret as ByteStreamQueryIQ; if ((response.ByteStreamQuery != null) && (response.ByteStreamQuery.Hosts != null) && (response.ByteStreamQuery.Hosts.Length > 0)) { strHost = response.ByteStreamQuery.Hosts[0].Host; strPort = response.ByteStreamQuery.Hosts[0].Port; strJID = response.ByteStreamQuery.Hosts[0].Jid; } } } } List<StreamHost> hosts = new List<StreamHost>(); /// See if we have a public IP for our local stream. If so, send it, and setup a local socks5 proxy //StreamHost hostloco = new StreamHost() { Host = strHost, Port = strPort, Jid = XMPPClient.JID }; #if !WINDOWS_PHONE if (FileTransferManager.UseLocalSOCKS5Server == true) { if ((FileTransferManager.SOCKS5ByteServerPublicIP != null) && (FileTransferManager.SOCKS5ByteServerPublicIP.Length > 0)) { FileTransferManager.StartSocks5ByteServer(); hosts.Add(new StreamHost() { Host = FileTransferManager.SOCKS5ByteServerPublicIP, Port = FileTransferManager.SOCKS5ByteServerPort.ToString(), Jid = XMPPClient.JID }); } else { IPAddress[] addresses = SocketServer.ConnectMgr.FindAddresses(); /// Find out which addresses are public, and if they are advertise them. (If they're private we can stun and use them in Jingle streams sessions, but not here) /// the one exception is if we let the user specify an address because they opened the port /// foreach (IPAddress address in addresses) { if (SocketServer.ConnectMgr.IsInPrivateRange(address) == false) { FileTransferManager.StartSocks5ByteServer(); /// Need a port to listen on for this address... needs socks5 server listening hosts.Add(new StreamHost() { Host = address.ToString(), Port = FileTransferManager.SOCKS5ByteServerPort.ToString(), Jid = XMPPClient.JID }); } } } } #endif hosts.Add(new StreamHost() { Host = strHost, Port = strPort, Jid = strJID }); //StreamHost host = new StreamHost() { Host = "192.168.1.124", Port = "7777", Jid = string.Format("proxy.{0}", XMPPClient.Domain) }; IQStart.ByteStreamQuery.Hosts = hosts.ToArray(); IQStart.ByteStreamQuery.Mode = StreamMode.tcp.ToString(); XMPPClient.SendObject(IQStart); } else { } base.Start(); }