protected virtual void DoUPnPExternalRecieveAccess() { try { tcpListener = new TcpConnectionListener(Port); tcpListener.Update += new FmdcEventHandler(DoUPnPExternalRecieveAccess_Update); tcpListener.Start(); // Don't do this if we don't have external ip if ( (Functions.UPnPDevices & Success) == Functions.UPnPDevices && (Functions.UPnPIGD & Success) == Functions.UPnPIGD && (Functions.UPnPExternalIp & Success) == Functions.UPnPExternalIp && (Functions.UPnPAddMapping & Success) == Functions.UPnPAddMapping && (Functions.UPnPGetMapping & Success) == Functions.UPnPGetMapping && (Functions.UPnPDeleteMapping & Success) == Functions.UPnPDeleteMapping ) { bool hasAddPortMapping = false; if (hasAddPortMapping = wanipService.AddPortMapping(this, mapping)) { //Transfer transfer = new Transfer(ExternalIPUPnP.ToString(), Port); Transfer transfer = new Transfer(ExternalIP.ToString(), Port); UserInfo me = new UserInfo(); me.DisplayName = "upnp"; me.TagInfo.Version = "FlowLibPowered"; transfer.Share = new Share("temp"); transfer.Me = me; transfer.Source = new Source(ExternalIP.ToString(), "upnp"); transferManager.AddTransferReq(new TransferRequest("upnp", null, new UserInfo())); transfer.Protocol = new TransferNmdcProtocol(transfer); transferManager.StartTransfer(transfer); // Wait 60 seconds before continue int i = 0; do { Thread.Sleep(50); } while (((Functions.UPnPExternalRecieveAccess & Success) != Functions.UPnPExternalRecieveAccess) && i++ > 1200); // clean; wanipService.DeletePortMapping(this, mapping); } } tcpListener.Update -= DoUPnPExternalRecieveAccess_Update; tcpListener.End(); tcpListener = null; } finally { Progress = Functions.End; } }
public void ActOnInMessage(IConMessage comMsg) { HubMessage message = (HubMessage)comMsg; if (message is MainChat) { MainChat main = (MainChat)message; MainMessage msg = new MainMessage(main.From, main.Content); Update(hub, new FmdcEventArgs(Actions.MainMessage, msg)); } else if (message is To) { To to = (To)message; PrivateMessage pm = new PrivateMessage(to.To, to.From, to.Content); Update(hub, new FmdcEventArgs(Actions.PrivateMessage, pm)); } else if (message is SR) { SR searchResult = (SR)message; SearchResultInfo srinfo = new SearchResultInfo(searchResult.Info, searchResult.From); Update(hub, new FmdcEventArgs(Actions.SearchResult, srinfo)); } else if (message is Search) { Search search = (Search)message; if (hub.Share == null) return; int maxReturns = 5; bool active = false; if (search.Address != null) { maxReturns = 10; active = true; } System.Collections.Generic.List<ContentInfo> ret = new System.Collections.Generic.List<ContentInfo>(maxReturns); // TODO : This lookup can be done nicer lock (hub.Share) { foreach (System.Collections.Generic.KeyValuePair<string, Containers.ContentInfo> var in hub.Share) { if (var.Value == null) continue; bool foundEnough = false; string ext = search.Info.Get(SearchInfo.EXTENTION); string sch = search.Info.Get(SearchInfo.SEARCH); if (ext != null && sch != null) { ContentInfo contentInfo = new ContentInfo(); if (search.Info.ContainsKey(SearchInfo.TYPE)) { switch (search.Info.Get(SearchInfo.TYPE)) { case "2": contentInfo.Set(ContentInfo.TTH, search.Info.Get(SearchInfo.SEARCH)); if (hub.Share.ContainsContent(ref contentInfo)) { ret.Add(contentInfo); } // We are looking through whole share here. // If no TTH matching. Ignore. foundEnough = true; break; case "1": default: if (var.Value.ContainsKey(ContentInfo.VIRTUAL) && (System.IO.Path.GetDirectoryName(var.Value.Get(ContentInfo.VIRTUAL)).IndexOf(sch, System.StringComparison.OrdinalIgnoreCase) != -1)) ret.Add(var.Value); break; } } if (!foundEnough) { string infoExt = System.IO.Path.GetExtension(var.Value.Get(ContentInfo.VIRTUAL)).TrimStart('.'); if ( var.Value.ContainsKey(ContentInfo.VIRTUAL) && (var.Value.Get(ContentInfo.VIRTUAL).IndexOf(sch, System.StringComparison.OrdinalIgnoreCase) != -1) && (ext.Length == 0 || ext.Contains(infoExt)) ) ret.Add(var.Value); } } if (foundEnough || ret.Count >= maxReturns) break; } } // Test against size restrictions for (int i = 0; i < ret.Count; i++) { bool send = true; long size = -1; try { size = long.Parse(search.Info.Get(SearchInfo.SIZE)); } catch { } if (search.Info.ContainsKey(SearchInfo.SIZETYPE) && size != -1) { switch (search.Info.Get(SearchInfo.SIZETYPE)) { case "1": // Min Size send = (size <= ret[i].Size); break; case "2": // Max Size send = (size >= ret[i].Size); break; case "3": // Equal Size send = (size == ret[i].Size); break; } } // Should this be sent? if (send) { SR sr = new SR(hub, ret[i], (search.Info.ContainsKey(SearchInfo.EXTENTION) ? search.Info.Get(SearchInfo.EXTENTION).Equals("$0") : false), search.From); if (active) { // Send with UDP UdpConnection.Send(sr, search.Address); } else { // Send through hub hub.Send(sr); } } } } else if (message is Lock) { hub.Send(new Supports(hub)); hub.Send(new Key(hub, ((Lock)message).Key)); hub.Send(new ValidateNick(hub)); } else if (message is HubNmdc.HubName) { HubNmdc.HubName hubname = (HubNmdc.HubName)message; Containers.HubName name = null; if (hubname.Topic != null) name = new Containers.HubName(hubname.Name, hubname.Topic); else name = new Containers.HubName(hubname.Content); Update(hub, new FmdcEventArgs(Actions.Name, name)); } else if (message is NickList) { NickList nicks = (NickList)message; foreach (string userid in nicks.List) { UserInfo userInfo = new UserInfo(); userInfo.DisplayName = userid; userInfo.Set(UserInfo.STOREID, hub.StoreId + userid); if (hub.GetUserById(userid) == null) Update(hub, new FmdcEventArgs(Actions.UserOnline, userInfo)); } } else if (message is OpList) { OpList ops = (OpList)message; foreach (string userid in ops.List) { UserInfo userInfo = new UserInfo(); userInfo.DisplayName = userid; userInfo.Set(UserInfo.STOREID, hub.StoreId + userid); userInfo.IsOperator = true; User usr = null; if ((usr = hub.GetUserById(userid)) == null) Update(hub, new FmdcEventArgs(Actions.UserOnline, userInfo)); else { usr.UserInfo = userInfo; Update(hub, new FmdcEventArgs(Actions.UserInfoChange, usr.UserInfo)); } } } else if (message is Quit) { Quit quit = (Quit)message; User usr = null; if ((usr = hub.GetUserById(quit.From)) != null) Update(hub, new FmdcEventArgs(Actions.UserOffline, usr.UserInfo)); } else if (message is LogedIn) hub.RegMode = 2; else if (message is ValidateDenide) Update(hub, new FmdcEventArgs(Actions.StatusChange, new HubStatus(HubStatus.Codes.Disconnected))); else if (message is GetPass) { hub.RegMode = 1; if (hub.HubSetting.Password.Length == 0) Update(hub, new FmdcEventArgs(Actions.Password, null)); else hub.Send(new MyPass(hub)); } else if (message is MyINFO) { MyINFO myinfo = (MyINFO)message; User usr = null; if ((usr = hub.GetUserById(message.From)) == null) Update(hub, new FmdcEventArgs(Actions.UserOnline, myinfo.UserInfo)); else { bool op = usr.IsOperator; usr.UserInfo = myinfo.UserInfo; usr.UserInfo.IsOperator = op; Update(hub, new FmdcEventArgs(Actions.UserInfoChange, usr.UserInfo)); } if (hub.RegMode >= 0 && string.Equals(myinfo.From, hub.Me.ID)) { IsReady = true; } } else if (message is Hello) { if (hub.HubSetting.DisplayName.Equals(message.From)) { hub.Send(new Version(hub)); hub.Send(new GetNickList(hub)); if (hub.RegMode < 0) hub.RegMode = 0; UpdateMyInfo(); } } else if (message is ConnectToMe) { ConnectToMe conToMe = (ConnectToMe)message; Transfer trans = new Transfer(conToMe.Address, conToMe.Port); trans.Share = this.hub.Share; trans.Me = hub.Me; trans.Source = new Source(hub.StoreId, null); // Protocol has to be set last. trans.Protocol = new TransferNmdcProtocol(trans); #if !COMPACT_FRAMEWORK if (conToMe.TLS && hub.Me.ContainsKey(UserInfo.SECURE)) trans.SecureProtocol = SecureProtocols.TLS; #endif Update(hub, new FmdcEventArgs(Actions.TransferStarted, trans)); } else if (message is RevConnectToMe) { RevConnectToMe revConToMe = (RevConnectToMe)message; User usr = null; usr = hub.GetUserById(revConToMe.From); if (hub.Me.Mode == FlowLib.Enums.ConnectionTypes.Passive) { if (usr != null) { // If user are not set as passive. Set it as it and respond with a revconnect. if (usr.UserInfo.Mode != FlowLib.Enums.ConnectionTypes.Passive) { usr.UserInfo.Mode = FlowLib.Enums.ConnectionTypes.Passive; hub.Send(new RevConnectToMe(revConToMe.From, hub)); } } } else { if (usr != null) { Update(hub, new FmdcEventArgs(Actions.TransferRequest, new TransferRequest(usr.ID, hub, usr.UserInfo))); #if !COMPACT_FRAMEWORK // Security, Windows Mobile doesnt support SSLStream so we disable this feature for it. if ( usr.UserInfo.ContainsKey(UserInfo.SECURE) && hub.Me.ContainsKey(UserInfo.SECURE) && !string.IsNullOrEmpty(hub.Me.Get(UserInfo.SECURE)) ) hub.Send(new ConnectToMe(usr.ID, hub.Share.Port, hub, SecureProtocols.TLS)); else #endif hub.Send(new ConnectToMe(usr.ID, hub.Share.Port, hub)); } } } else if (message is ForceMove) { ForceMove forceMove = (ForceMove)message; hub.Disconnect(); Update(hub, new FmdcEventArgs(Actions.Redirect, new RedirectInfo(forceMove.Address))); } }
protected virtual void DoInternalListenRecieveAccess() { try { tcpListener = new TcpConnectionListener(Port); tcpListener.Update += new FmdcEventHandler(DoInternalListenAccess_Update); tcpListener.Start(); try { // TODO: We shouldn't limit ourself to IPv4. Transfer transfer = new Transfer("127.0.0.1", Port); UserInfo me = new UserInfo(); me.DisplayName = "loopback"; me.TagInfo.Version = "FlowLibPowered"; transfer.Share = new Share("temp"); transfer.Me = me; // TODO: We shouldn't limit ourself to IPv4. transfer.Source = new Source("127.0.0.1", "loopback"); transferManager.AddTransferReq(new TransferRequest("loopback", null, new UserInfo())); transfer.Protocol = new TransferNmdcProtocol(transfer); transferManager.StartTransfer(transfer); Success |= Functions.InternalListenAccess; } catch { // We do not have InternalListenAccess. Success = Success & ~Functions.InternalListenAccess; } // Wait 10 seconds before continue int i = 0; do { Thread.Sleep(50); } while (((Functions.InternalRecieveAccess & Success) != Functions.InternalRecieveAccess) && i++ > 200); // clean; tcpListener.Update -= DoInternalListenAccess_Update; tcpListener.End(); tcpListener = null; } finally { Progress = Functions.ExternalIp; } }
protected virtual void DoExternalRecieveAccess() { try { tcpListener = new TcpConnectionListener(Port); tcpListener.Update += new FmdcEventHandler(DoExternalRecieveAccess_Update); tcpListener.Start(); // Don't do this if we don't have external ip if ((Functions.ExternalIp & Success) == Functions.ExternalIp) { Transfer transfer = new Transfer(ExternalIP.ToString(), Port); UserInfo me = new UserInfo(); me.DisplayName = "external"; me.TagInfo.Version = "FlowLibPowered"; transfer.Share = new Share("temp"); transfer.Me = me; transfer.Source = new Source(ExternalIP.ToString(), "external"); transferManager.AddTransferReq(new TransferRequest("external", null, new UserInfo())); transfer.Protocol = new TransferNmdcProtocol(transfer); transferManager.StartTransfer(transfer); } // Wait 30 seconds before continue int i = 0; do { Thread.Sleep(50); } while (((Functions.ExternalRecieveAccess & Success) != Functions.ExternalRecieveAccess) && i++ > 600); // clean; tcpListener.Update -= DoExternalRecieveAccess_Update; tcpListener.End(); tcpListener = null; } finally { if ((Functions.ExternalRecieveAccess & Success) == Functions.ExternalRecieveAccess) { Progress = Functions.End; } else { Progress = Functions.UPnPDevices; } } }
public void ActOnInMessage(IConMessage conMsg) { StrMessage message = (StrMessage)conMsg; #region INF if (message is INF) { INF inf = (INF)message; if (hub != null && inf.Type.Equals("I")) { if (hub.RegMode < 0) hub.RegMode = 0; UpdateInf(); Info = inf.UserInfo; if (hub != null && Info.Description == null) Update(con, new FmdcEventArgs(Actions.Name, new Containers.HubName(Info.DisplayName))); else if (hub != null) Update(con, new FmdcEventArgs(Actions.Name, new Containers.HubName(Info.DisplayName, Info.Description))); } else if (trans != null && inf.Type.Equals("C")) { string token = null; // CINF IDE3VACJVAXNOQLGRFQS7D5HYH4A6GLZDO3LJ33HQ TO2718662518 if (trans.Me != null && trans.Me.ContainsKey("TO")) token = trans.Me.Get("TO"); else if (inf.UserInfo.ContainsKey("TO")) token = inf.UserInfo.Get("TO"); TransferRequest req = new TransferRequest(token, null, inf.UserInfo); FmdcEventArgs eArgs = new FmdcEventArgs(0, req); RequestTransfer(trans, eArgs); req = eArgs.Data as TransferRequest; if (!eArgs.Handled || req == null) { // Can't see user/connection on my allow list trans.Disconnect("No match for Request"); return; } if (!((req.User.ContainsKey(UserInfo.CID) && inf.UserInfo.ContainsKey(UserInfo.CID)) && req.User.Get(UserInfo.CID).Equals(inf.UserInfo.Get(UserInfo.CID)))) { // For some reason user is trying to tell us it is a diffrent user. We dont like that. FmdcEventArgs e = new FmdcEventArgs((int)TransferErrors.USERID_MISMATCH); Error(trans, e); if (!e.Handled) { trans.Disconnect("User Id Mismatch"); return; } } if (trans.Me == null) trans.Me = req.Me; trans.User = req.User; info = trans.User; trans.Share = req.Share; trans.Source = req.Source; download = req.Download; con.Send(new INF(con, trans.Me)); if (download) { EnsureCurrentSegmentCancelation(); // Request new segment from user. IF we have found one. ELSE disconnect. if (GetSegment(true)) { OnDownload(); } else trans.Disconnect("All content downloaded"); } } else if (hub != null) { User usr = null; if ((usr = hub.GetUserById(inf.Id)) == null) { if (inf.UserInfo.Mode == ConnectionTypes.Unknown) { inf.UserInfo.Mode = ConnectionTypes.Passive; } Update(con, new FmdcEventArgs(Actions.UserOnline, inf.UserInfo)); } else { usr.UserInfo = inf.UserInfo; Update(con, new FmdcEventArgs(Actions.UserInfoChange, usr.UserInfo)); } // This is so we update our own reg/op hub count. if (string.Equals(hub.Me.ID,inf.Id)) { // Should we be marked with key? bool regmodeChanged = false; if (hub.RegMode < 2) { if (((UserInfo.ACCOUNT_FLAG_OPERATOR & inf.UserInfo.Account) == UserInfo.ACCOUNT_FLAG_OPERATOR)) { hub.RegMode = 2; regmodeChanged = true; } else if (((UserInfo.ACCOUNT_FLAG_SUPERUSER & inf.UserInfo.Account) == UserInfo.ACCOUNT_FLAG_SUPERUSER)) { hub.RegMode = 2; regmodeChanged = true; } else if (((UserInfo.ACCOUNT_FLAG_HUBOWNER & inf.UserInfo.Account) == UserInfo.ACCOUNT_FLAG_HUBOWNER)) { hub.RegMode = 2; regmodeChanged = true; } } // Should we be marked as reg? if (hub.RegMode < 1) { if (((UserInfo.ACCOUNT_FLAG_REGISTERED & inf.UserInfo.Account) == UserInfo.ACCOUNT_FLAG_REGISTERED)) { hub.RegMode = 1; regmodeChanged = true; } } if (regmodeChanged) UpdateInf(); IsReady = true; } } } #endregion #region MSG else if (message is MSG && hub != null) { MSG msg = (MSG)message; if (msg.PmGroup == null) { MainMessage main = new MainMessage(msg.From, msg.Content); Update(con, new FmdcEventArgs(Actions.MainMessage, main)); } else { PrivateMessage pm = new PrivateMessage(msg.To, msg.From, msg.Content, msg.PmGroup); Update(con, new FmdcEventArgs(Actions.PrivateMessage, pm)); } } #endregion #region SID else if (message is SID && hub != null) { SID sid = (SID)message; hub.Me.Set(UserInfo.SID, sid.Id); } #endregion #region STA else if (message is STA) { STA sta = (STA)message; if (hub != null) { MainMessage main = new MainMessage(info.ID, sta.Content); Update(con, new FmdcEventArgs(Actions.MainMessage, main)); } } #endregion #region GPA else if (message is GPA) { GPA gpa = (GPA)message; this.gpaString = gpa.RandomData; if (trans != null) { Update(con, new FmdcEventArgs(Actions.Password, null)); } if (hub != null && hub.HubSetting.Password.Length == 0) { Update(con, new FmdcEventArgs(Actions.Password, null)); } else hub.Send(new PAS(hub, gpa.RandomData, hub.HubSetting.Password)); } #endregion #region QUI else if (message is QUI && hub != null) { QUI qui = (QUI)message; User usr = null; if ((usr = hub.GetUserById(qui.Id)) != null) { Update(con, new FmdcEventArgs(Actions.UserOffline, usr.UserInfo)); if (usr.ID == hub.Me.ID) { // TODO : Banning and redirect handling hub.Disconnect(); // Redirect if (!string.IsNullOrEmpty(qui.Address)) Update(con, new FmdcEventArgs(Actions.Redirect, new RedirectInfo(qui.Address, qui.Message, qui.DisconnectedBy))); // Banned else { if (qui.Time != -1) // Sets reconnect attempt to infinite hub.KeepAliveInterval = 0; else hub.KeepAliveInterval = qui.Time; Update(con, new FmdcEventArgs(Actions.Banned, new BannedInfo(qui.Time, qui.Message, qui.DisconnectedBy))); } } } } #endregion #region SUP else if (message is SUP) { if (trans != null && !hasSentSUP) { con.Send(new SUP(con)); } supports = (SUP)message; // TODO : We should really care about what hub support. if (!supports.BASE && !supports.TIGR) { // We will just simply disconnect if hub doesnt support this right now con.Disconnect("Connection doesnt support BASE or BAS0"); } #if !COMPACT_FRAMEWORK // Encrypted transfers if (supports.ADCS) { if ( (hub != null && hub.Me.ContainsKey(UserInfo.SECURE)) || (trans != null && trans.Me.ContainsKey(UserInfo.SECURE)) ) { con.SecureProtocol = SecureProtocols.TLS; } } #endif } #endregion #region RES else if (message is RES) { RES res = (RES)message; SearchResultInfo srinfo = new SearchResultInfo(res.Info, res.Id, res.Token); if (hub != null) Update(con, new FmdcEventArgs(Actions.SearchResult, srinfo)); } #endregion #region SCH else if (message is SCH) { SCH sch = (SCH)message; UserInfo usr = null; if (hub != null) { User u = hub.GetUserById(sch.Id); if (u != null) usr = u.UserInfo; } else if (trans != null) usr = trans.User; SendRES(sch.Info, usr); } #endregion #region CTM else if (message is CTM && hub != null) { CTM ctm = (CTM)message; // We really hate buggy hubsofts. Only reason we will get this message is because hubsoft dont know diffrent between E and D messages. if (ctm.Id == hub.Me.ID) return; User usr = null; string addr = null; // Do we support same protocol? double version = 0.0; if (ctm.Protocol != null && (ctm.Protocol.StartsWith("ADC/") || ctm.Protocol.StartsWith("ADCS/"))) { try { version = double.Parse(ctm.Protocol.Substring( ctm.Protocol.IndexOf("/") +1), CultureInfo.GetCultureInfo("en-GB").NumberFormat); } catch { } } if (version > 1.0) { hub.Send(new STA(hub, ctm.Id, hub.Me.ID, "241", "Protocol is not supported. I only support ADC 1.0/ADCS 0.10 and prior", "TO" + ctm.Token + " PR" + ctm.Protocol)); return; } if ((usr = hub.GetUserById(ctm.Id)) != null && usr.UserInfo.ContainsKey(UserInfo.IP)) { addr = usr.UserInfo.Get(UserInfo.IP); Transfer trans = new Transfer(addr, ctm.Port); trans.Share = hub.Share; // We are doing this because we want to filter out PID and so on. User me = hub.GetUserById(hub.Me.ID); trans.Me = new UserInfo(me.UserInfo); trans.Protocol = new AdcProtocol(trans); #if !COMPACT_FRAMEWORK if (ctm.Secure) trans.SecureProtocol = SecureProtocols.TLS; #endif // Support for prior versions of adc then 1.0 string token = ctm.Token; if (version < 1.0 && ctm.Token.StartsWith("TO")) token = ctm.Token.Substring(2); trans.Me.Set("TO", token); Update(con, new FmdcEventArgs(Actions.TransferRequest, new TransferRequest(token, hub, usr.UserInfo,false))); Update(con, new FmdcEventArgs(Actions.TransferStarted, trans)); } } #endregion #region RCM else if (message is RCM && hub != null) { RCM rcm = (RCM)message; // We really hate buggy hubsofts. Only reason we will get this message is because hubsoft dont know diffrent between E and D messages. if (rcm.Id == hub.Me.ID) return; if (hub.Me.Mode != FlowLib.Enums.ConnectionTypes.Passive && hub.Share != null) { User usr = null; if ((usr = hub.GetUserById(rcm.Id)) != null) { // Do we support same protocol? double version = 0.0; if (rcm.Protocol != null && (rcm.Protocol.StartsWith("ADC/") || rcm.Protocol.StartsWith("ADCS/"))) { try { version = double.Parse(rcm.Protocol.Substring(rcm.Protocol.IndexOf("/") + 1), CultureInfo.GetCultureInfo("en-GB").NumberFormat); } catch { } if (version <= 1.0) { // Support for prior versions of adc then 1.0 string token = rcm.Token; if (version < 1.0 && rcm.Token.StartsWith("TO")) token = rcm.Token.Substring(2); Update(con, new FmdcEventArgs(Actions.TransferRequest, new TransferRequest(token, hub, usr.UserInfo, false))); if (rcm.Secure && hub.Me.ContainsKey(UserInfo.SECURE)) hub.Send(new CTM(hub, rcm.Id, rcm.IDTwo, rcm.Protocol, int.Parse(0 + hub.Me.Get(UserInfo.SECURE)), token)); else hub.Send(new CTM(hub, rcm.Id, rcm.IDTwo, rcm.Protocol, hub.Share.Port, token)); } else { hub.Send(new STA(hub, rcm.Id, hub.Me.ID, "241", "Protocol is not supported. I only support ADC 1.0 and prior", "TO" + rcm.Token + " PR" + rcm.Protocol)); return; } } } } else { // TODO : we should probably return a STA message. } } #endregion #region GFI else if (message is GFI && this.trans != null) { GFI gfi = (GFI)message; if (gfi.Identifier != null) { trans.Content = new ContentInfo(); switch (gfi.ContentType) { case "file": // Requesting file // This is because we have support for old DC++ client and mods like (DCDM who has ASCII encoding) if (gfi.Identifier.Equals("files.xml.bz2")) { trans.Content.Set(ContentInfo.FILELIST, Utils.FileLists.BaseFilelist.XMLBZ); trans.Content.Set(ContentInfo.VIRTUAL, System.Text.Encoding.UTF8.WebName + gfi.Identifier); } else if (gfi.Identifier.StartsWith("TTH/")) { trans.Content.Set(ContentInfo.TTH, gfi.Identifier.Substring(4)); } else { trans.Content.Set(ContentInfo.VIRTUAL, gfi.Identifier); } break; case "list": // TODO : We dont care about what subdirectoy user whats list for trans.Content.Set(ContentInfo.FILELIST, Utils.FileLists.BaseFilelist.XML); trans.Content.Set(ContentInfo.VIRTUAL, System.Text.Encoding.UTF8.WebName + "files.xml"); break; default: // We are not supporting type. Disconnect con.Send(new STA(con, "251", "Type not known:" + gfi.ContentType, null)); con.Disconnect(); return; } SearchInfo si = new SearchInfo(); if (trans.Content.ContainsKey(ContentInfo.TTH)) si.Set(SearchInfo.TYPE, trans.Content.Get(ContentInfo.TTH)); si.Set(SearchInfo.SEARCH, trans.Content.Get(ContentInfo.VIRTUAL)); SendRES(si, trans.User); } } #endregion #region GET else if (message is GET && this.trans != null) { GET get = (GET)message; // If we are supposed to download and other client tries to download. Disconnect. if (trans != null && this.download) { trans.Disconnect(); return; } bool firstTime = true; if (get.Identifier != null) { trans.Content = new ContentInfo(); switch (get.ContentType) { case "file": // Requesting file // This is because we have support for old DC++ client and mods like (DCDM who has ASCII encoding) if (get.Identifier.Equals("files.xml.bz2")) { trans.Content.Set(ContentInfo.FILELIST, Utils.FileLists.BaseFilelist.XMLBZ); trans.Content.Set(ContentInfo.VIRTUAL, System.Text.Encoding.UTF8.WebName + get.Identifier); } else if (get.Identifier.StartsWith("TTH/")) { trans.Content.Set(ContentInfo.TTH, get.Identifier.Substring(4)); } else { trans.Content.Set(ContentInfo.VIRTUAL, get.Identifier); } break; case "list": // TODO : We dont care about what subdirectoy user whats list for trans.Content.Set(ContentInfo.FILELIST, Utils.FileLists.BaseFilelist.XML); trans.Content.Set(ContentInfo.VIRTUAL, System.Text.Encoding.UTF8.WebName + "files.xml"); break; case "tthl": // TTH/DQSGG2MYKKLXX4N2P7TBPKSC5HVBO3ISYZPLMWA if (get.Identifier.StartsWith("TTH/")) { trans.Content.Set(ContentInfo.TTH, get.Identifier.Substring(4)); ContentInfo tmp = trans.Content; if (con.Share != null && con.Share.ContainsContent(ref tmp) && tmp.ContainsKey(ContentInfo.TTHL)) { byte[] bytes = Utils.Convert.Base32.Decode(tmp.Get(ContentInfo.TTHL)); #if !COMPACT_FRAMEWORK trans.CurrentSegment = new SegmentInfo(-1, 0, bytes.LongLength); #else trans.CurrentSegment = new SegmentInfo(-1, 0, bytes.Length); #endif con.Send(new SND(trans, get.ContentType, get.Identifier, new SegmentInfo(-1, trans.CurrentSegment.Start, trans.CurrentSegment.Length))); // Send content to user System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes); ms.Flush(); bytes = ms.ToArray(); con.Send(new BinaryMessage(con, bytes, bytes.Length)); System.Console.WriteLine("TTH Leaves:" + FlowLib.Utils.Convert.Base32.Encode(bytes)); firstTime = true; } } if (!firstTime) { // We should not get here if file is in share. con.Send(new STA(con, "251", "File not available", null)); con.Disconnect(); } return; default: // We are not supporting type. Disconnect con.Send(new STA(con, "251", "Type not known:" + get.ContentType, null)); con.Disconnect(); return; } trans.CurrentSegment = get.SegmentInfo; byte[] bytesToSend = null; try { // TODO : ZLib compression here doesnt work as we want. It takes much memory and much cpu //Util.Compression.ZLib zlib = null; //if (adcget.ZL1) // zlib = new Fmdc.Util.Compression.ZLib(); while (connectionStatus != TcpConnection.Disconnected && (bytesToSend = GetContent(System.Text.Encoding.UTF8, trans.CurrentSegment.Position, trans.CurrentSegment.Length - trans.CurrentSegment.Position)) != null) { if (firstTime) { con.Send(new SND(trans, get.ContentType, get.Identifier, new SegmentInfo(-1, get.SegmentInfo.Start, trans.CurrentSegment.Length))); firstTime = false; } trans.CurrentSegment.Position += bytesToSend.Length; // We want to compress content with ZLib //if (zlib != null) //{ // zlib.Compress2(bytesToSend); // bytesToSend = zlib.Read(); //} con.Send(new BinaryMessage(trans, bytesToSend, bytesToSend.Length)); bytesToSend = null; } // If we compressing data with zlib. We need to send ending bytes too. //if (zlib != null && connectionStatus != Connection.Disconnected) // trans.Send(new ConMessage(trans, zlib.close())); } catch (System.Exception e) { System.Console.WriteLine("ERROR:" + e); } } trans.CurrentSegment = new SegmentInfo(-1); trans.Content = null; if (firstTime) { // We should not get here if file is in share. con.Send(new STA(con, "251", "File not available", null)); con.Disconnect(); } } #endregion #region SND else if (message is SND) { SND snd = (SND)message; if (!trans.Content.Get(ContentInfo.REQUEST).Equals(snd.Identifier)) { trans.Disconnect("I want my bytes.."); return; } if (trans.DownloadItem.ContentInfo.Size == -1) { trans.DownloadItem.ContentInfo.Size = snd.SegmentInfo.Length; trans.DownloadItem.SegmentSize = snd.SegmentInfo.Length; EnsureCurrentSegmentCancelation(); GetSegment(false); } else if (trans.CurrentSegment != null && trans.CurrentSegment.Length != snd.SegmentInfo.Length) { trans.Disconnect("Why would i want to get a diffrent length of bytes then i asked for?"); return; } this.IsRawData = true; trans.ShouldBlockOnSend = true; } #endregion }
public AdcProtocol(Transfer trans) : this((ITransfer)trans) { this.trans = trans; this.trans.ConnectionStatusChange += new FmdcEventHandler(trans_ConnectionStatusChange); }
protected void OnStartConnection(IAsyncResult ar) { try { Socket s = (Socket)ar.AsyncState; Transfer t = new Transfer(s.EndAccept(ar)); FmdcEventArgs e = new FmdcEventArgs(Actions.TransferStarted, t); Update(this, e); if (!e.Handled) t.Disconnect(); SetupConnection(s); } catch (ObjectDisposedException) { /* End has been called */ } }