예제 #1
0
        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;
            }
        }
예제 #2
0
        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)));
            }
        }
예제 #3
0
        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;
            }
        }
예제 #4
0
        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;
                }
            }
        }
예제 #5
0
        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
        }
예제 #6
0
 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 */ }
 }