dimples 0.3.3__tar.gz → 0.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dimples-0.3.3 → dimples-0.3.4}/PKG-INFO +1 -1
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/packer.py +44 -3
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/packer.py +6 -42
- {dimples-0.3.3 → dimples-0.3.4}/dimples/conn/gatekeeper.py +8 -1
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/t_login.py +1 -1
- {dimples-0.3.3 → dimples-0.3.4}/dimples/group/emitter.py +1 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/server/broadcast.py +25 -4
- {dimples-0.3.3 → dimples-0.3.4}/dimples/server/cpu/handshake.py +6 -2
- {dimples-0.3.3 → dimples-0.3.4}/dimples/server/cpu/report.py +1 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/server/dispatcher.py +3 -0
- dimples-0.3.4/dimples/server/messenger.py +106 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/server/packer.py +2 -13
- dimples-0.3.4/dimples/server/processor.py +278 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/server/session.py +4 -5
- {dimples-0.3.3 → dimples-0.3.4}/dimples/utils/__init__.py +30 -2
- {dimples-0.3.3 → dimples-0.3.4}/dimples.egg-info/PKG-INFO +1 -1
- {dimples-0.3.3 → dimples-0.3.4}/setup.py +1 -1
- dimples-0.3.3/dimples/server/messenger.py +0 -185
- dimples-0.3.3/dimples/server/processor.py +0 -132
- {dimples-0.3.3 → dimples-0.3.4}/README.md +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/archivist.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/checkpoint.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/cpu/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/cpu/commands.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/cpu/creator.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/cpu/group.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/cpu/grp_expel.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/cpu/grp_invite.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/cpu/grp_join.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/cpu/grp_query.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/cpu/grp_quit.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/cpu/grp_reset.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/cpu/grp_resign.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/cpu/handshake.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/facebook.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/messenger.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/network/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/network/session.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/network/state.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/network/transition.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/processor.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/client/terminal.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/anonymous.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/ans.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/archivist.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/compat/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/compat/btc.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/compat/compatible.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/compat/entity.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/compat/meta.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/compat/network.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/dbi/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/dbi/account.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/dbi/message.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/dbi/session.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/facebook.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/messenger.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/protocol/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/protocol/ans.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/protocol/block.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/protocol/handshake.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/protocol/login.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/protocol/mute.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/protocol/report.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/register.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/common/session.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/conn/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/conn/gate.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/conn/mars.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/conn/mtp.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/conn/protocol/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/conn/protocol/mars.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/conn/protocol/ws.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/conn/queue.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/conn/seeker.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/conn/session.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/conn/ws.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/account.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/dos/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/dos/base.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/dos/document.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/dos/group.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/dos/group_history.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/dos/group_keys.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/dos/login.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/dos/meta.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/dos/private.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/dos/station.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/dos/user.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/message.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/session.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/t_cipherkey.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/t_document.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/t_group.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/t_group_history.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/t_group_keys.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/t_message.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/t_meta.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/t_private.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/t_station.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/database/t_user.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/edge/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/edge/octopus.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/edge/shared.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/edge/start.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/group/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/group/admin.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/group/builder.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/group/delegate.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/group/helper.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/group/manager.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/group/packer.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/register/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/register/base.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/register/ext.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/register/run.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/register/shared.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/server/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/server/archivist.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/server/cpu/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/server/cpu/ans.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/server/cpu/document.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/server/cpu/login.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/server/push.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/server/session_center.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/server/trace.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/station/__init__.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/station/handler.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/station/shared.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/station/start.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/utils/cache.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/utils/config.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/utils/dos.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/utils/log.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples/utils/singleton.py +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples.egg-info/SOURCES.txt +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples.egg-info/dependency_links.txt +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples.egg-info/entry_points.txt +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples.egg-info/requires.txt +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/dimples.egg-info/top_level.txt +0 -0
- {dimples-0.3.3 → dimples-0.3.4}/setup.cfg +0 -0
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
from typing import Optional
|
|
31
31
|
|
|
32
32
|
from dimsdk import ID
|
|
33
|
-
from dimsdk import InstantMessage, ReliableMessage
|
|
33
|
+
from dimsdk import InstantMessage, SecureMessage, ReliableMessage
|
|
34
34
|
|
|
35
35
|
from ..utils import get_msg_sig
|
|
36
36
|
from ..common import CommonMessagePacker
|
|
@@ -40,14 +40,14 @@ from .checkpoint import Checkpoint
|
|
|
40
40
|
class ClientMessagePacker(CommonMessagePacker):
|
|
41
41
|
|
|
42
42
|
# Override
|
|
43
|
-
def
|
|
43
|
+
def _check_receiver(self, msg: InstantMessage) -> bool:
|
|
44
44
|
receiver = msg.receiver
|
|
45
45
|
if receiver.is_broadcast:
|
|
46
46
|
# broadcast message
|
|
47
47
|
return True
|
|
48
48
|
elif receiver.is_user:
|
|
49
49
|
# check user's meta & document
|
|
50
|
-
return super().
|
|
50
|
+
return super()._check_receiver(msg=msg)
|
|
51
51
|
#
|
|
52
52
|
# check group's meta & members
|
|
53
53
|
#
|
|
@@ -85,6 +85,47 @@ class ClientMessagePacker(CommonMessagePacker):
|
|
|
85
85
|
# when the member's visa is responded, we should send the suspended message again.
|
|
86
86
|
return len(waiting) < len(members)
|
|
87
87
|
|
|
88
|
+
# protected
|
|
89
|
+
def _check_group(self, msg: ReliableMessage) -> bool:
|
|
90
|
+
receiver = msg.receiver
|
|
91
|
+
# check group
|
|
92
|
+
group = ID.parse(identifier=msg.get('group'))
|
|
93
|
+
if group is None and receiver.is_group:
|
|
94
|
+
# Transform:
|
|
95
|
+
# (B) => (J)
|
|
96
|
+
# (D) => (G)
|
|
97
|
+
group = receiver
|
|
98
|
+
if group is None or group.is_broadcast:
|
|
99
|
+
# A, C - personal message (or hidden group message)
|
|
100
|
+
# the packer will call the facebook to select a user from local
|
|
101
|
+
# for this receiver, if no user matched (private key not found),
|
|
102
|
+
# this message will be ignored;
|
|
103
|
+
# E, F, G - broadcast group message
|
|
104
|
+
# broadcast message is not encrypted, so it can be read by anyone.
|
|
105
|
+
return True
|
|
106
|
+
# H, J, K - group message
|
|
107
|
+
# check for received group message
|
|
108
|
+
members = self._members(group=group)
|
|
109
|
+
if len(members) > 0:
|
|
110
|
+
# group is ready
|
|
111
|
+
return True
|
|
112
|
+
# group not ready, suspend message for waiting members
|
|
113
|
+
error = {
|
|
114
|
+
'message': 'group not ready',
|
|
115
|
+
'group': str(receiver),
|
|
116
|
+
}
|
|
117
|
+
self.suspend_reliable_message(msg=msg, error=error) # msg['error'] = error
|
|
118
|
+
return False
|
|
119
|
+
|
|
120
|
+
# Override
|
|
121
|
+
def verify_message(self, msg: ReliableMessage) -> Optional[SecureMessage]:
|
|
122
|
+
# check receiver/group with local user
|
|
123
|
+
if not self._check_group(msg=msg):
|
|
124
|
+
# receiver (group) not ready
|
|
125
|
+
self.warning(msg='receiver not ready: %s' % msg.receiver)
|
|
126
|
+
return None
|
|
127
|
+
return super().verify_message(msg=msg)
|
|
128
|
+
|
|
88
129
|
# # Override
|
|
89
130
|
# def serialize_message(self, msg: ReliableMessage) -> bytes:
|
|
90
131
|
# attach_key_digest(msg=msg, messenger=self.messenger)
|
|
@@ -109,7 +109,7 @@ class CommonMessagePacker(MessagePacker, Logging, ABC):
|
|
|
109
109
|
return self.facebook.members(identifier=group)
|
|
110
110
|
|
|
111
111
|
# protected
|
|
112
|
-
def
|
|
112
|
+
def _check_sender(self, msg: ReliableMessage) -> bool:
|
|
113
113
|
""" Check sender before verifying received message """
|
|
114
114
|
sender = msg.sender
|
|
115
115
|
assert sender.is_user, 'sender error: %s' % sender
|
|
@@ -132,39 +132,7 @@ class CommonMessagePacker(MessagePacker, Logging, ABC):
|
|
|
132
132
|
return False
|
|
133
133
|
|
|
134
134
|
# protected
|
|
135
|
-
def
|
|
136
|
-
receiver = msg.receiver
|
|
137
|
-
# check group
|
|
138
|
-
group = ID.parse(identifier=msg.get('group'))
|
|
139
|
-
if group is None and receiver.is_group:
|
|
140
|
-
# Transform:
|
|
141
|
-
# (B) => (J)
|
|
142
|
-
# (D) => (G)
|
|
143
|
-
group = receiver
|
|
144
|
-
if group is None or group.is_broadcast:
|
|
145
|
-
# A, C - personal message (or hidden group message)
|
|
146
|
-
# the packer will call the facebook to select a user from local
|
|
147
|
-
# for this receiver, if no user matched (private key not found),
|
|
148
|
-
# this message will be ignored;
|
|
149
|
-
# E, F, G - broadcast group message
|
|
150
|
-
# broadcast message is not encrypted, so it can be read by anyone.
|
|
151
|
-
return True
|
|
152
|
-
# H, J, K - group message
|
|
153
|
-
# check for received group message
|
|
154
|
-
members = self._members(group=group)
|
|
155
|
-
if len(members) > 0:
|
|
156
|
-
# group is ready
|
|
157
|
-
return True
|
|
158
|
-
# group not ready, suspend message for waiting members
|
|
159
|
-
error = {
|
|
160
|
-
'message': 'group not ready',
|
|
161
|
-
'group': str(receiver),
|
|
162
|
-
}
|
|
163
|
-
self.suspend_reliable_message(msg=msg, error=error) # msg['error'] = error
|
|
164
|
-
return False
|
|
165
|
-
|
|
166
|
-
# protected
|
|
167
|
-
def _check_instant_message_receiver(self, msg: InstantMessage) -> bool:
|
|
135
|
+
def _check_receiver(self, msg: InstantMessage) -> bool:
|
|
168
136
|
""" Check receiver before encrypting message """
|
|
169
137
|
receiver = msg.receiver
|
|
170
138
|
if receiver.is_broadcast:
|
|
@@ -196,7 +164,7 @@ class CommonMessagePacker(MessagePacker, Logging, ABC):
|
|
|
196
164
|
def encrypt_message(self, msg: InstantMessage) -> Optional[SecureMessage]:
|
|
197
165
|
# 1. check contact info
|
|
198
166
|
# 2. check group members info
|
|
199
|
-
if not self.
|
|
167
|
+
if not self._check_receiver(msg=msg):
|
|
200
168
|
# receiver not ready
|
|
201
169
|
self.warning(msg='receiver not ready: %s' % msg.receiver)
|
|
202
170
|
return None
|
|
@@ -221,16 +189,12 @@ class CommonMessagePacker(MessagePacker, Logging, ABC):
|
|
|
221
189
|
|
|
222
190
|
# Override
|
|
223
191
|
def verify_message(self, msg: ReliableMessage) -> Optional[SecureMessage]:
|
|
224
|
-
# 1. check
|
|
225
|
-
|
|
192
|
+
# 1. check receiver/group with local user
|
|
193
|
+
# 2. check sender's meta
|
|
194
|
+
if not self._check_sender(msg=msg):
|
|
226
195
|
# sender not ready
|
|
227
196
|
self.warning(msg='sender not ready: %s' % msg.sender)
|
|
228
197
|
return None
|
|
229
|
-
# 2. check receiver/group with local user
|
|
230
|
-
if not self._check_reliable_message_receiver(msg=msg):
|
|
231
|
-
# receiver (group) not ready
|
|
232
|
-
self.warning(msg='receiver not ready: %s' % msg.receiver)
|
|
233
|
-
return None
|
|
234
198
|
return super().verify_message(msg=msg)
|
|
235
199
|
|
|
236
200
|
# Override
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
|
|
31
31
|
import socket
|
|
32
32
|
import time
|
|
33
|
+
import traceback
|
|
33
34
|
from typing import Optional, Tuple
|
|
34
35
|
|
|
35
36
|
from dimsdk import ReliableMessage
|
|
@@ -44,12 +45,13 @@ from tcp import StreamChannel
|
|
|
44
45
|
from tcp import ServerHub, ClientHub
|
|
45
46
|
|
|
46
47
|
from ..utils import get_remote_address, get_local_address
|
|
48
|
+
from ..utils import get_msg_info
|
|
47
49
|
from ..utils import Runner, Logging
|
|
48
50
|
|
|
49
51
|
from .protocol import DeparturePacker
|
|
50
52
|
|
|
51
53
|
from .gate import CommonGate, TCPServerGate, TCPClientGate
|
|
52
|
-
from .queue import MessageQueue
|
|
54
|
+
from .queue import MessageQueue, MessageWrapper
|
|
53
55
|
|
|
54
56
|
|
|
55
57
|
class StreamServerHub(ServerHub):
|
|
@@ -209,6 +211,7 @@ class GateKeeper(Runner, DockerDelegate, Logging):
|
|
|
209
211
|
return True
|
|
210
212
|
except Exception as e:
|
|
211
213
|
self.error(msg='process error: %s' % e)
|
|
214
|
+
traceback.print_exc()
|
|
212
215
|
return False
|
|
213
216
|
if not self.active:
|
|
214
217
|
# inactive, wait a while to check again
|
|
@@ -264,3 +267,7 @@ class GateKeeper(Runner, DockerDelegate, Logging):
|
|
|
264
267
|
# Override
|
|
265
268
|
def docker_error(self, error: IOError, ship: Departure, docker: Docker):
|
|
266
269
|
self.error(msg='docker error while sending ship: %s, %s' % (ship, docker))
|
|
270
|
+
if isinstance(ship, MessageWrapper):
|
|
271
|
+
msg = ship.msg
|
|
272
|
+
if msg is not None:
|
|
273
|
+
self.error(msg='error message: %s' % get_msg_info(msg=msg))
|
|
@@ -155,6 +155,7 @@ class GroupEmitter(Logging):
|
|
|
155
155
|
success = self.__split_send_message(msg=msg, members=members, group=group, priority=priority)
|
|
156
156
|
self.info(msg='split %d message(s) for group: %s' % (success, group))
|
|
157
157
|
else:
|
|
158
|
+
self.info(msg='splitting message for %d members of group: %s' % (len(members), group))
|
|
158
159
|
# encrypt and sign this message first,
|
|
159
160
|
# then split and send to all members one by one
|
|
160
161
|
return self.__disperse_message(msg=msg, members=members, group=group, priority=priority)
|
|
@@ -43,7 +43,7 @@ from ..utils import Singleton, Log, Logging
|
|
|
43
43
|
from ..common import StationInfo
|
|
44
44
|
|
|
45
45
|
from .cpu import AnsCommandProcessor
|
|
46
|
-
from .trace import TraceManager
|
|
46
|
+
from .trace import TraceNode, TraceList, TraceManager
|
|
47
47
|
from .dispatcher import Dispatcher
|
|
48
48
|
from .session_center import SessionCenter
|
|
49
49
|
|
|
@@ -173,6 +173,9 @@ def broadcast_reliable_message(msg: ReliableMessage, station: ID):
|
|
|
173
173
|
# delivering via station bridge, should we mark 'sent_neighbors' in
|
|
174
174
|
# only one message to the bridge, let the bridge to separate for other
|
|
175
175
|
# neighbors which not connect to this station directly?
|
|
176
|
+
# set trace nodes
|
|
177
|
+
tm = TraceManager()
|
|
178
|
+
tm.set_nodes(msg=msg, nodes=recipients)
|
|
176
179
|
# OK
|
|
177
180
|
Log.info(msg='Broadcast message delivered: %s => %s' % (sender, recipients))
|
|
178
181
|
return len(recipients)
|
|
@@ -186,13 +189,31 @@ def deliver_message(msg: ReliableMessage, receiver: ID, recipients: Set[ID], sta
|
|
|
186
189
|
Log.warning(msg='skip sender: %s, %s' % (receiver, recipients))
|
|
187
190
|
return None
|
|
188
191
|
assert isinstance(recipients, set), 'recipients error: %s' % recipients
|
|
192
|
+
tm = TraceManager()
|
|
193
|
+
traces = tm.get_traces(msg=msg)
|
|
194
|
+
if traces.search(node=receiver) >= 0:
|
|
195
|
+
Log.warning(msg='skip cycled message: %s, %s' % (msg.sender, receiver))
|
|
196
|
+
return None
|
|
189
197
|
# clone
|
|
190
198
|
msg = ReliableMessage.parse(msg=msg.dictionary)
|
|
199
|
+
traces = copy_traces(traces=traces)
|
|
200
|
+
# add these recipients into traces, exclude current receiver
|
|
191
201
|
recipients = recipients.copy()
|
|
192
202
|
recipients.discard(receiver) # exclude receiver
|
|
193
203
|
recipients.add(station) # include current station
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
204
|
+
for mta in recipients:
|
|
205
|
+
node = TraceNode.create(identifier=mta)
|
|
206
|
+
traces.insert(node=node)
|
|
207
|
+
msg['traces'] = TraceNode.revert(nodes=traces.nodes)
|
|
197
208
|
# deliver message with traces
|
|
198
209
|
return dispatcher.deliver_message(msg=msg, receiver=receiver)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def copy_traces(traces: TraceList) -> TraceList:
|
|
213
|
+
when = traces.time
|
|
214
|
+
if when is None:
|
|
215
|
+
when = DateTime.now()
|
|
216
|
+
else:
|
|
217
|
+
when = DateTime.parse(value=when)
|
|
218
|
+
nodes = traces.nodes
|
|
219
|
+
return TraceList(msg_time=when, traces=nodes.copy())
|
|
@@ -67,11 +67,15 @@ class HandshakeCommandProcessor(BaseCommandProcessor):
|
|
|
67
67
|
# set/update session in session server with new session key
|
|
68
68
|
messenger = self.messenger
|
|
69
69
|
session = messenger.session
|
|
70
|
+
sess_id = session.identifier
|
|
71
|
+
sender = r_msg.sender
|
|
72
|
+
if sess_id is not None:
|
|
73
|
+
assert sess_id == sender, 'sender error: %s, %s' % (sender, sess_id)
|
|
70
74
|
if session.key == content.session:
|
|
71
75
|
# session key match
|
|
72
|
-
Log.info(msg='handshake accepted: %s, session: %s' % (
|
|
76
|
+
Log.info(msg='handshake accepted: %s, session: %s' % (sender, session.key))
|
|
73
77
|
# verified success
|
|
74
|
-
handshake_accepted(identifier=
|
|
78
|
+
handshake_accepted(identifier=sender, session=session, messenger=messenger)
|
|
75
79
|
res = HandshakeCommand.success(session=session.key)
|
|
76
80
|
else:
|
|
77
81
|
# session key not match
|
|
@@ -59,6 +59,7 @@ class ReportCommandProcessor(BaseCommandProcessor, Logging):
|
|
|
59
59
|
if session.identifier is None:
|
|
60
60
|
self.error(msg='session not login, drop report command: %s => %s' % (sender, content))
|
|
61
61
|
return []
|
|
62
|
+
# FIXME: send via bridge?
|
|
62
63
|
assert sender == session.identifier, 'report sender error: %s not %s' % (sender, session.identifier)
|
|
63
64
|
# check report title
|
|
64
65
|
title = content.title
|
|
@@ -185,6 +185,9 @@ class Dispatcher(MessageDeliver):
|
|
|
185
185
|
if receiver.type == EntityType.STATION or msg.sender.type == EntityType.STATION:
|
|
186
186
|
# no need to save station message
|
|
187
187
|
return False
|
|
188
|
+
elif msg.receiver.is_broadcast:
|
|
189
|
+
# no need to save broadcast message
|
|
190
|
+
return False
|
|
188
191
|
db = self.__mdb
|
|
189
192
|
return db.cache_reliable_message(msg=msg, receiver=receiver)
|
|
190
193
|
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# ==============================================================================
|
|
3
|
+
# MIT License
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2019 Albert Moky
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
# ==============================================================================
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
Messenger for request handler in station
|
|
28
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
29
|
+
|
|
30
|
+
Transform and send message
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
from typing import List
|
|
34
|
+
|
|
35
|
+
from dimsdk import ID
|
|
36
|
+
from dimsdk import Station
|
|
37
|
+
from dimsdk import ReliableMessage
|
|
38
|
+
from dimsdk import MessageHelper
|
|
39
|
+
|
|
40
|
+
from ..common import CommonMessenger, CommonMessagePacker
|
|
41
|
+
|
|
42
|
+
from .dispatcher import Dispatcher
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class ServerMessenger(CommonMessenger):
|
|
46
|
+
|
|
47
|
+
# Override
|
|
48
|
+
def handshake_success(self):
|
|
49
|
+
session = self.session
|
|
50
|
+
identifier = session.identifier
|
|
51
|
+
remote_address = session.remote_address
|
|
52
|
+
self.warning(msg='user login: %s, socket: %s' % (identifier, remote_address))
|
|
53
|
+
# process suspended messages
|
|
54
|
+
self._resume_reliable_messages()
|
|
55
|
+
|
|
56
|
+
def _resume_reliable_messages(self):
|
|
57
|
+
packer = self.packer
|
|
58
|
+
assert isinstance(packer, CommonMessagePacker), 'message packer error: %s' % packer
|
|
59
|
+
messages = packer.resume_reliable_messages()
|
|
60
|
+
for msg in messages:
|
|
61
|
+
self.info(msg='processing suspended message: %s -> %s' % (msg.sender, msg.receiver))
|
|
62
|
+
try:
|
|
63
|
+
responses = self.process_reliable_message(msg=msg)
|
|
64
|
+
for res in responses:
|
|
65
|
+
self.send_reliable_message(msg=res, priority=1)
|
|
66
|
+
except Exception as error:
|
|
67
|
+
self.error(msg='failed to process incoming message: %s' % error)
|
|
68
|
+
|
|
69
|
+
# Override
|
|
70
|
+
def process_reliable_message(self, msg: ReliableMessage) -> List[ReliableMessage]:
|
|
71
|
+
session = self.session
|
|
72
|
+
current = self.facebook.current_user
|
|
73
|
+
sid = current.identifier
|
|
74
|
+
receiver = msg.receiver
|
|
75
|
+
# call super
|
|
76
|
+
responses = super().process_reliable_message(msg=msg)
|
|
77
|
+
# check for first handshake
|
|
78
|
+
if receiver == Station.ANY or msg.group == Station.EVERY:
|
|
79
|
+
# if this message sent to 'station@anywhere', or with group ID 'stations@everywhere',
|
|
80
|
+
# it means the client doesn't have the station's meta (e.g.: first handshaking)
|
|
81
|
+
# or visa maybe expired, here attach them to the first response.
|
|
82
|
+
for res in responses:
|
|
83
|
+
if res.sender == sid:
|
|
84
|
+
# let the first responding message to carry the station's meta & visa
|
|
85
|
+
MessageHelper.set_meta(meta=current.meta, msg=res)
|
|
86
|
+
MessageHelper.set_visa(visa=current.visa, msg=res)
|
|
87
|
+
break
|
|
88
|
+
elif session.identifier == sid:
|
|
89
|
+
# station bridge
|
|
90
|
+
responses = pick_out(messages=responses, bridge=sid)
|
|
91
|
+
return responses
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def pick_out(messages: List[ReliableMessage], bridge: ID) -> List[ReliableMessage]:
|
|
95
|
+
responses = []
|
|
96
|
+
dispatcher = Dispatcher()
|
|
97
|
+
for msg in messages:
|
|
98
|
+
receiver = msg.receiver
|
|
99
|
+
if receiver == bridge:
|
|
100
|
+
# respond to the bridge
|
|
101
|
+
responses.append(msg)
|
|
102
|
+
else:
|
|
103
|
+
# this message is not respond to the bridge, the receiver may be
|
|
104
|
+
# roaming to other station, so deliver it via dispatcher here.
|
|
105
|
+
dispatcher.deliver_message(msg=msg, receiver=receiver)
|
|
106
|
+
return responses
|
|
@@ -85,15 +85,13 @@ class ServerMessagePacker(CommonMessagePacker):
|
|
|
85
85
|
# cycled message
|
|
86
86
|
if sender.type == EntityType.STATION or receiver.type == EntityType.STATION:
|
|
87
87
|
# ignore cycled station message
|
|
88
|
+
self.warning(msg='cycled station message: %s -> %s' % (sender, receiver))
|
|
88
89
|
return None
|
|
89
90
|
elif receiver.is_broadcast:
|
|
90
91
|
# ignore cycled broadcast message
|
|
92
|
+
self.warning(msg='cycled broadcast message: %s -> %s' % (sender, receiver))
|
|
91
93
|
return None
|
|
92
94
|
self.warning(msg='cycled message: %s -> %s' % (sender, receiver))
|
|
93
|
-
if not self.__check_reliable_message_receiver(msg=msg):
|
|
94
|
-
# receiver (group) not ready
|
|
95
|
-
self.warning(msg='receiver not ready: %s' % msg.receiver)
|
|
96
|
-
return None
|
|
97
95
|
# check session
|
|
98
96
|
if self.__is_trusted(sender=msg.sender):
|
|
99
97
|
# no need to verify message from this sender
|
|
@@ -102,15 +100,6 @@ class ServerMessagePacker(CommonMessagePacker):
|
|
|
102
100
|
# verify after sender is OK
|
|
103
101
|
return super().verify_message(msg=msg)
|
|
104
102
|
|
|
105
|
-
# Override
|
|
106
|
-
def _check_reliable_message_receiver(self, msg: ReliableMessage) -> bool:
|
|
107
|
-
# skip for "super().verify_message(msg=msg)"
|
|
108
|
-
return True
|
|
109
|
-
|
|
110
|
-
def __check_reliable_message_receiver(self, msg: ReliableMessage) -> bool:
|
|
111
|
-
# check for group
|
|
112
|
-
return super()._check_reliable_message_receiver(msg=msg)
|
|
113
|
-
|
|
114
103
|
|
|
115
104
|
def get_facebook(packer: CommonMessagePacker) -> CommonFacebook:
|
|
116
105
|
barrack = packer.facebook
|