예제 #1
0
        public OpBuddy AddBuddy(string name, byte[] key)
        {
            ulong id = Utilities.KeytoID(key);

            OpBuddy buddy;

            if (BuddyList.TryGetValue(id, out buddy))
            {
                return(buddy);
            }

            buddy = new OpBuddy()
            {
                ID = id, Name = name, Key = key
            };

            BuddyList.SafeAdd(id, buddy);

            Core.IndexName(id, name); // always associate this buddy with name

            SaveList = true;
            Core.RunInGuiThread(GuiUpdate);

            Core.Locations.Research(id);

            return(buddy);
        }
예제 #2
0
파일: PlanService.cs 프로젝트: nandub/DeOps
        public PlanService(OpCore core)
        {
            Core     = core;
            Network  = core.Network;
            Protocol = Network.Protocol;
            Store    = Network.Store;
            Trust    = Core.Trust;

            if (Core.Sim != null)
            {
                SaveInterval = 30;
            }

            Core.SecondTimerEvent += Core_SecondTimer;

            Cache = new VersionedCache(Network, ServiceID, DataTypeFile, false);

            Cache.FileAquired += new FileAquiredHandler(Cache_FileAquired);
            Cache.FileRemoved += new FileRemovedHandler(Cache_FileRemoved);
            Cache.Load();

            if (!PlanMap.SafeContainsKey(Core.UserID))
            {
                LocalPlan = new OpPlan(new OpVersionedFile(Core.User.Settings.KeyPublic));
                LocalPlan.Init();
                LocalPlan.Loaded = true;
                PlanMap.SafeAdd(Core.UserID, LocalPlan);
            }
        }
예제 #3
0
        public ChatRoom CreateRoom(string name, RoomKind kind)
        {
            ulong id = Utilities.RandUInt64(Core.RndGen);

            if (kind == RoomKind.Public)
            {
                id = ChatService.GetPublicRoomID(name);
            }

            ChatRoom room = new ChatRoom(kind, id, name);

            room.Active = true;
            room.AddMember(Core.UserID);

            RoomMap.SafeAdd(id, room);

            if (kind == RoomKind.Secret)
            {
                room.Host = Core.UserID;
                room.Verified[Core.UserID] = true;
                SendInviteRequest(room, Core.UserID); // send invite to copies of ourself that exist
            }

            Core.RunInGuiThread(Refresh);

            if (room.PublishRoom)
            {
                SetupPublic(room);
            }

            return(room);
        }
예제 #4
0
파일: OpCore.cs 프로젝트: nandub/DeOps
        public void IndexName(ulong user, string name)
        {
            Debug.Assert(name != null && name != "");
            if (name == null || name.Trim() == "")
            {
                return;
            }

            if (NameMap.SafeContainsKey(user))
            {
                return;
            }

            NameMap.SafeAdd(user, name);
        }
예제 #5
0
        private void Cache_FileAquired(OpVersionedFile file)
        {
            if (file.UserID != Network.Local.UserID)
            {
                return;
            }

            // only we can open the buddly list stored on the network
            byte[] key = Core.User.Settings.KeyPair.Decrypt(file.Header.FileKey, false);

            using (TaggedStream tagged = new TaggedStream(Cache.GetFilePath(file.Header), Network.Protocol))
                using (IVCryptoStream crypto = IVCryptoStream.Load(tagged, key))
                {
                    BuddyList.SafeClear();

                    PacketStream stream = new PacketStream(crypto, Network.Protocol, FileAccess.Read);

                    G2Header root = null;

                    while (stream.ReadPacket(ref root))
                    {
                        if (root.Name == BuddyPacket.Buddy)
                        {
                            OpBuddy buddy = OpBuddy.Decode(root);
                            ulong   id    = Utilities.KeytoID(buddy.Key);

                            Core.IndexKey(id, ref buddy.Key);
                            Core.IndexName(id, buddy.Name);

                            if (buddy.Ignored)
                            {
                                IgnoreList.SafeAdd(id, buddy);
                            }
                            else
                            {
                                BuddyList.SafeAdd(id, buddy);
                            }
                        }
                    }
                }

            Core.RunInGuiThread(GuiUpdate);
        }
예제 #6
0
파일: IMService.cs 프로젝트: nandub/DeOps
        private IMStatus OpenStatus(ulong user)
        {
            IMStatus status;

            if (!IMMap.SafeTryGetValue(user, out status))
            {
                status = new IMStatus(user);
                IMMap.SafeAdd(user, status);
            }

            return(status);
        }
예제 #7
0
        public ShareService(OpCore core)
        {
            Core    = core;
            Network = core.Network;

            string rootPath = Core.User.RootPath + Path.DirectorySeparatorChar +
                              "Data" + Path.DirectorySeparatorChar +
                              ServiceID.ToString() + Path.DirectorySeparatorChar;

            SharePath = rootPath + DataTypeShare.ToString() + Path.DirectorySeparatorChar;
            Directory.CreateDirectory(SharePath);

            HeaderPath = SharePath + Utilities.CryptFilename(Core, "ShareHeaders");

            PublicPath = rootPath + DataTypePublic.ToString() + Path.DirectorySeparatorChar;
            Directory.CreateDirectory(PublicPath);

            DownloadPath = Core.User.RootPath + Path.DirectorySeparatorChar + "Downloads" + Path.DirectorySeparatorChar;


            Core.SecondTimerEvent += Core_SecondTimer;

            // data
            Network.RudpControl.SessionUpdate += new SessionUpdateHandler(Session_Update);
            Network.RudpControl.SessionData[ServiceID, DataTypeSession] += new SessionDataHandler(Session_Data);

            Core.Transfers.FileSearch[ServiceID, DataTypeShare]  += new FileSearchHandler(Transfers_FileSearch);
            Core.Transfers.FileRequest[ServiceID, DataTypeShare] += new FileRequestHandler(Transfers_FileRequest);

            Core.Transfers.FileSearch[ServiceID, DataTypePublic]  += new FileSearchHandler(Transfers_PublicSearch);
            Core.Transfers.FileRequest[ServiceID, DataTypePublic] += new FileRequestHandler(Transfers_PublicRequest);

            // location
            TempLocation = new TempCache(Network, ServiceID, DataTypeLocation);

            Local = new ShareCollection(Core.UserID);
            Collections.SafeAdd(Core.UserID, Local);

            LoadHeaders();
        }
예제 #8
0
        private void Cache_FileAquired(OpVersionedFile file)
        {
            // get profile
            OpProfile prevProfile = GetProfile(file.UserID);

            OpProfile newProfile = new OpProfile(file);

            ProfileMap.SafeAdd(file.UserID, newProfile);


            if (file.UserID == Core.UserID)
            {
                LocalProfile = newProfile;
            }

            if ((newProfile == LocalProfile) || (prevProfile != null && prevProfile.Loaded))
            {
                LoadProfile(newProfile.UserID);
            }


            // update subs
            if (Network.Established)
            {
                List <LocationData> locations = new List <LocationData>();

                Trust.ProjectRoots.LockReading(delegate()
                {
                    foreach (uint project in Trust.ProjectRoots.Keys)
                    {
                        if (newProfile.UserID == Core.UserID || Trust.IsHigher(newProfile.UserID, project))
                        {
                            Trust.GetLocsBelow(Core.UserID, project, locations);
                        }
                    }
                });

                Store.PublishDirect(locations, newProfile.UserID, ServiceID, 0, file.SignedHeader);
            }

            if (ProfileUpdate != null)
            {
                Core.RunInGuiThread(ProfileUpdate, newProfile);
            }

            if (Core.NewsWorthy(newProfile.UserID, 0, false))
            {
                Core.MakeNews(ServiceIDs.Profile, "Profile updated by " + Core.GetName(newProfile.UserID), newProfile.UserID, 0, true);
            }
        }
예제 #9
0
        private void LoadHeaderFile(string path, OpStorage storage, bool reload, bool working)
        {
            try
            {
                if (!File.Exists(path))
                {
                    return;
                }

                bool cached = Network.Routing.InCacheArea(storage.UserID);
                bool local  = false;

                byte[] key = working ? LocalFileKey : storage.File.Header.FileKey;

                using (TaggedStream filex = new TaggedStream(path, Network.Protocol))
                    using (IVCryptoStream crypto = IVCryptoStream.Load(filex, key))
                    {
                        PacketStream stream = new PacketStream(crypto, Protocol, FileAccess.Read);

                        G2Header header = null;

                        ulong currentUID = 0;

                        while (stream.ReadPacket(ref header))
                        {
                            if (!working && header.Name == StoragePacket.Root)
                            {
                                StorageRoot packet = StorageRoot.Decode(header);

                                local = Core.UserID == storage.UserID ||
                                        GetHigherRegion(Core.UserID, packet.ProjectID).Contains(storage.UserID) ||
                                        Trust.GetDownlinkIDs(Core.UserID, packet.ProjectID, 1).Contains(storage.UserID);
                            }

                            if (header.Name == StoragePacket.File)
                            {
                                StorageFile packet = StorageFile.Decode(header);

                                if (packet == null)
                                {
                                    continue;
                                }

                                bool historyFile = true;
                                if (packet.UID != currentUID)
                                {
                                    historyFile = false;
                                    currentUID  = packet.UID;
                                }

                                OpFile file = null;
                                if (!FileMap.SafeTryGetValue(packet.HashID, out file))
                                {
                                    file = new OpFile(packet);
                                    FileMap.SafeAdd(packet.HashID, file);
                                }

                                InternalFileMap.SafeAdd(packet.InternalHashID, file);

                                if (!reload)
                                {
                                    file.References++;
                                }

                                if (!working) // if one ref is public, then whole file is marked public
                                {
                                    file.Working = false;
                                }

                                if (packet.HashID == 0 || packet.InternalHash == null)
                                {
                                    Debug.Assert(false);
                                    continue;
                                }

                                string filepath = GetFilePath(packet.HashID);
                                file.Downloaded = File.Exists(filepath);

                                if (Loading && file.Downloaded && !ReferencedPaths.Contains(filepath))
                                {
                                    ReferencedPaths.Add(filepath);
                                }

                                if (!file.Downloaded)
                                {
                                    // if in local range only store latest
                                    if (local && !historyFile)
                                    {
                                        DownloadFile(storage.UserID, packet);
                                    }

                                    // if storage is in cache range, download all files
                                    else if (Network.Established && cached)
                                    {
                                        DownloadFile(storage.UserID, packet);
                                    }
                                }

                                // on link update, if in local range, get latest files
                                // (handled by location update, when it sees a new version of storage component is available)
                            }
                        }
                    }
            }
            catch (Exception ex)
            {
                Core.Network.UpdateLog("Storage", "Error loading files " + ex.Message);
            }
        }
예제 #10
0
        void Cache_FileAquired(OpVersionedFile file)
        {
            // unload old file
            OpStorage prevStorage = GetStorage(file.UserID);

            if (prevStorage != null)
            {
                string oldPath = GetFilePath(prevStorage);

                UnloadHeaderFile(oldPath, prevStorage.File.Header.FileKey);
            }

            OpStorage newStorage = new OpStorage(file);

            StorageMap.SafeAdd(file.UserID, newStorage);


            LoadHeaderFile(GetFilePath(newStorage), newStorage, false, false);

            // record changes of higher nodes for auto-integration purposes
            Trust.ProjectRoots.LockReading(delegate()
            {
                foreach (uint project in Trust.ProjectRoots.Keys)
                {
                    List <ulong> inheritIDs = Trust.GetAutoInheritIDs(Core.UserID, project);

                    if (Core.UserID == newStorage.UserID || inheritIDs.Contains(newStorage.UserID))
                    {
                        // doesnt get called on startup because working not initialized before headers are loaded
                        if (Working.ContainsKey(project))
                        {
                            bool doSave = Working[project].RefreshHigherChanges(newStorage.UserID);

                            if (!Loading && !SavingLocal)
                            {
                                Working[project].AutoIntegrate(doSave);
                            }
                        }
                    }
                }
            });

            // update subs - this ensures file not propagated lower until we have it (prevents flood to original poster)
            if (Network.Established)
            {
                List <LocationData> locations = new List <LocationData>();

                Trust.ProjectRoots.LockReading(delegate()
                {
                    foreach (uint project in Trust.ProjectRoots.Keys)
                    {
                        if (newStorage.UserID == Core.UserID || Trust.IsHigher(newStorage.UserID, project))
                        {
                            Trust.GetLocsBelow(Core.UserID, project, locations);
                        }
                    }
                });

                Store.PublishDirect(locations, newStorage.UserID, ServiceID, FileTypeCache, file.SignedHeader);
            }

            if (StorageUpdate != null)
            {
                Core.RunInGuiThread(StorageUpdate, newStorage);
            }

            if (Core.NewsWorthy(newStorage.UserID, 0, false))
            {
                Core.MakeNews(ServiceIDs.Storage, "File System updated by " + Core.GetName(newStorage.UserID), newStorage.UserID, 0, false);
            }
        }
예제 #11
0
        private void CacheFile(SignedData signedHeader, VersionedFileHeader header)
        {
            if (Core.InvokeRequired)
            {
                Debug.Assert(false);
            }

            try
            {
                // check if file exists
                string path = "";
                if (header.FileHash != null)
                {
                    path = GetFilePath(header);
                    if (!File.Exists(path))
                    {
                        Download(signedHeader, header);
                        return;
                    }
                }

                // get file
                OpVersionedFile prevFile = GetFile(header.KeyID);

                if (prevFile != null)
                {
                    if (header.Version < prevFile.Header.Version)
                    {
                        return; // dont update with older version
                    }
                }
                OpVersionedFile newFile = new OpVersionedFile(header.Key);


                // set new header
                newFile.Header       = header;
                newFile.SignedHeader = signedHeader.Encode(Network.Protocol);
                newFile.Unique       = !Network.Established;

                FileMap.SafeAdd(header.KeyID, newFile);

                RunSaveHeaders = true;

                if (FileAquired != null)
                {
                    FileAquired.Invoke(newFile);
                }


                // delete old file - do after aquired event so invoked (storage) can perform clean up operation
                if (prevFile != null && prevFile.Header.FileHash != null)
                {
                    string oldPath = GetFilePath(prevFile.Header);
                    if (path != oldPath && File.Exists(oldPath))
                    {
                        try { File.Delete(oldPath); }
                        catch { }
                    }
                }
            }
            catch (Exception ex)
            {
                Core.Network.UpdateLog("VersionedFile", "Error caching data " + ex.Message);
            }
        }
예제 #12
0
파일: InternetSim.cs 프로젝트: nandub/DeOps
        void PumpThread(int index)
        {
            while (true)
            {
                PumpStart[index].WaitOne();

                if (Shutdown)
                {
                    return;
                }


                // send packets
                foreach (SimPacket packet in InPackets[index])
                {
                    switch (packet.Type)
                    {
                    case SimPacketType.Udp:
                        packet.Dest.Core.Sim.BytesRecvd += (ulong)packet.Packet.Length;
                        packet.Dest.UdpControl.OnReceive(packet.Packet, packet.Packet.Length, packet.Source);
                        break;

                    case SimPacketType.TcpConnect:
                        TcpConnect socket = packet.Dest.TcpControl.OnAccept(null, packet.Source);

                        if (socket != null)
                        {
                            TcpSourcetoDest.SafeAdd(packet.Tcp, socket);
                            TcpSourcetoDest.SafeAdd(socket, packet.Tcp);

                            packet.Tcp.OnConnect();
                        }

                        break;

                    case SimPacketType.Tcp:
                        TcpConnect dest;
                        if (TcpSourcetoDest.SafeTryGetValue(packet.Tcp, out dest))
                        {
                            dest.Core.Sim.BytesRecvd += (ulong)packet.Packet.Length;

                            packet.Packet.CopyTo(dest.RecvBuffer, dest.RecvBuffSize);
                            dest.OnReceive(packet.Packet.Length);
                        }
                        break;

                    case SimPacketType.TcpClose:
                        TcpConnect destClose;
                        if (TcpSourcetoDest.SafeTryGetValue(packet.Tcp, out destClose))
                        {
                            destClose.OnReceive(0);

                            TcpSourcetoDest.SafeRemove(packet.Tcp);
                            TcpSourcetoDest.SafeRemove(destClose);
                        }
                        break;
                    }
                }

                // send messages from gui
                if (!TestCoreThread)
                {
                    Instances.SafeForEach(instance =>
                    {
                        if (instance.ThreadIndex != index)
                        {
                            return;
                        }

                        Action <OpCore> runMessages = core =>
                        {
                            // process invoked functions, dequeue quickly to continue processing
                            while (core.CoreMessages.Count > 0)
                            {
                                AsyncCoreFunction function = null;

                                lock (core.CoreMessages)
                                    function = core.CoreMessages.Dequeue();

                                if (function != null)
                                {
                                    function.Result    = function.Method.DynamicInvoke(function.Args);
                                    function.Completed = true;
                                    function.Processed.Set();
                                }
                            }
                        };

                        if (instance.Context.Lookup != null)
                        {
                            runMessages(instance.Context.Lookup);
                        }

                        instance.Context.Cores.SafeForEach(c => runMessages(c));
                    });
                }

                // instance timer
                if (CurrentPump == 0) // stepping would cause second timer to run every 250ms without this
                {
                    Instances.SafeForEach(instance =>
                    {
                        if (instance.ThreadIndex == index)
                        {
                            instance.Context.SecondTimer_Tick(null);
                        }
                    });
                }

                PumpEnd[index].Set();
            }
        }
예제 #13
0
        private void Process_LocationData(DataReq data, SignedData signed, LocationData location)
        {
            Core.IndexKey(location.UserID, ref location.Key);

            Debug.Assert(location.UserID == location.Source.UserID);
            if (location.UserID != location.Source.UserID)
            {
                return;
            }


            ClientInfo client = GetLocationInfo(location.UserID, location.Source.ClientID);

            // check location version
            if (client != null)
            {
                if (location.Version == client.Data.Version)
                {
                    return;
                }

                else if (location.Version < client.Data.Version)
                {
                    if (data != null && data.Source != null)
                    {
                        Network.Store.Send_StoreReq(data.Source, data.LocalProxy, new DataReq(null, client.Data.UserID, ServiceID, 0, client.SignedData));
                    }

                    return;
                }
            }

            Core.IndexName(location.UserID, location.Name);

            // notify components of new versions (usually just localsync service signed up for this)
            DhtAddress address = new DhtAddress(location.IP, location.Source);

            foreach (PatchTag tag in location.Tags)
            {
                if (TagReceived.Contains(tag.Service, tag.DataType))
                {
                    TagReceived[tag.Service, tag.DataType].Invoke(address, location.UserID, tag.Tag);
                }
            }


            // add location
            if (client == null)
            {
                // if too many clients, and not us, return
                if (location.UserID != Core.UserID && ActiveClientCount(location.UserID) > MaxClientsperUser)
                {
                    return;
                }

                client = new ClientInfo(location);

                Clients.SafeAdd(client.RoutingID, client);

                // dont need to worry about remote caching old locs indefinitely because if a loc is cached remotely
                // that means the remote is being continuall pinged, or else the loc would expire
                // if we're still interested in loc after a min, it will be pinged locally
            }

            client.Data       = location;
            client.SignedData = signed.Encode(Network.Protocol);

            if (client.Data.UserID == Core.UserID && client.Data.Source.ClientID == Network.Local.ClientID)
            {
                LocalClient = client;
            }


            AddRoutingData(location);

            // only get down here if loc was new version in first place (recently published)
            // with live comm trickle down this prevents highers from being direct ping flooded to find their
            // online status
            client.LastSeen = Core.TimeNow;

            SignalUpdate(client, true);
        }