Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit f370265

Browse files
committed
Merge branch 'develop' of github.com:matrix-org/synapse into erikj/filter_speed
2 parents 02514b0 + 0d1c85e commit f370265

25 files changed

+483
-137
lines changed

CHANGES.rst

+44
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,47 @@
1+
Changes in synapse v0.20.0-rc1 (2017-03-30)
2+
===========================================
3+
4+
Features:
5+
6+
* Add delete_devices API (PR #1993)
7+
* Add phone number registration/login support (PR #1994, #2055)
8+
9+
10+
Changes:
11+
12+
* Use JSONSchema for validation of filters. Thanks @pik! (PR #1783)
13+
* Reread log config on SIGHUP (PR #1982)
14+
* Speed up public room list (PR #1989)
15+
* Add helpful texts to logger config options (PR #1990)
16+
* Minor ``/sync`` performance improvements. (PR #2002, #2013, #2022)
17+
* Add some debug to help diagnose weird federation issue (PR #2035)
18+
* Correctly limit retries for all federation requests (PR #2050, #2061)
19+
* Don't lock table when persisting new one time keys (PR #2053)
20+
* Reduce some CPU work on DB threads (PR #2054)
21+
* Cache hosts in room (PR #2060)
22+
* Batch sending of device list pokes (PR #2063)
23+
* Speed up persist event path in certain edge cases (PR #2070)
24+
25+
26+
Bug fixes:
27+
28+
* Fix bug where current_state_events renamed to current_state_ids (PR #1849)
29+
* Fix routing loop when fetching remote media (PR #1992)
30+
* Fix current_state_events table to not lie (PR #1996)
31+
* Fix CAS login to handle PartialDownloadError (PR #1997)
32+
* Fix assertion to stop transaction queue getting wedged (PR #2010)
33+
* Fix presence to fallback to last_active_ts if it beats the last sync time.
34+
Thanks @Half-Shot! (PR #2014)
35+
* Fix bug when federation received a PDU while a room join is in progress (PR
36+
#2016)
37+
* Fix resetting state on rejected events (PR #2025)
38+
* Fix installation issues in readme. Thanks @ricco386 (PR #2037)
39+
* Fix caching of remote servers' signature keys (PR #2042)
40+
* Fix some leaking log context (PR #2048, #2049, #2057, #2058)
41+
* Fix rejection of invites not reaching sync (PR #2056)
42+
43+
44+
145
Changes in synapse v0.19.3 (2017-03-20)
246
=======================================
347

README.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,10 @@ Installing prerequisites on ArchLinux::
108108
sudo pacman -S base-devel python2 python-pip \
109109
python-setuptools python-virtualenv sqlite3
110110

111-
Installing prerequisites on CentOS 7::
111+
Installing prerequisites on CentOS 7 or Fedora 25::
112112

113113
sudo yum install libtiff-devel libjpeg-devel libzip-devel freetype-devel \
114-
lcms2-devel libwebp-devel tcl-devel tk-devel \
114+
lcms2-devel libwebp-devel tcl-devel tk-devel redhat-rpm-config \
115115
python-virtualenv libffi-devel openssl-devel
116116
sudo yum groupinstall "Development Tools"
117117

docs/log_contexts.rst

+8-3
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,14 @@ That doesn't follow the rules, but we can fix it by wrapping it with
204204
This technique works equally for external functions which return deferreds,
205205
or deferreds we have made ourselves.
206206

207-
XXX: think this is what ``preserve_context_over_deferred`` is supposed to do,
208-
though it is broken, in that it only restores the logcontext for the duration
209-
of the callbacks, which doesn't comply with the logcontext rules.
207+
You can also use ``logcontext.make_deferred_yieldable``, which just does the
208+
boilerplate for you, so the above could be written:
209+
210+
.. code:: python
211+
212+
def sleep(seconds):
213+
return logcontext.make_deferred_yieldable(get_sleep_deferred(seconds))
214+
210215
211216
Fire-and-forget
212217
---------------

docs/postgres.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ script one last time, e.g. if the SQLite database is at ``homeserver.db``
112112
run::
113113

114114
synapse_port_db --sqlite-database homeserver.db \
115-
--postgres-config database_config.yaml
115+
--postgres-config homeserver-postgres.yaml
116116

117117
Once that has completed, change the synapse config to point at the PostgreSQL
118-
database configuration file using the ``database_config`` parameter (see
119-
`Synapse Config`_) and restart synapse. Synapse should now be running against
118+
database configuration file ``homeserver-postgres.yaml`` (i.e. rename it to
119+
``homeserver.yaml``) and restart synapse. Synapse should now be running against
120120
PostgreSQL.

docs/turn-howto.rst

+34-4
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,37 @@ You may be able to setup coturn via your package manager, or set it up manually
5050

5151
pwgen -s 64 1
5252

53-
5. Ensure youe firewall allows traffic into the TURN server on
53+
5. Consider your security settings. TURN lets users request a relay
54+
which will connect to arbitrary IP addresses and ports. At the least
55+
we recommend:
56+
57+
# VoIP traffic is all UDP. There is no reason to let users connect to arbitrary TCP endpoints via the relay.
58+
no-tcp-relay
59+
60+
# don't let the relay ever try to connect to private IP address ranges within your network (if any)
61+
# given the turn server is likely behind your firewall, remember to include any privileged public IPs too.
62+
denied-peer-ip=10.0.0.0-10.255.255.255
63+
denied-peer-ip=192.168.0.0-192.168.255.255
64+
denied-peer-ip=172.16.0.0-172.31.255.255
65+
66+
# special case the turn server itself so that client->TURN->TURN->client flows work
67+
allowed-peer-ip=10.0.0.1
68+
69+
# consider whether you want to limit the quota of relayed streams per user (or total) to avoid risk of DoS.
70+
user-quota=12 # 4 streams per video call, so 12 streams = 3 simultaneous relayed calls per user.
71+
total-quota=1200
72+
73+
Ideally coturn should refuse to relay traffic which isn't SRTP;
74+
see https://github.com/matrix-org/synapse/issues/2009
75+
76+
6. Ensure your firewall allows traffic into the TURN server on
5477
the ports you've configured it to listen on (remember to allow
55-
both TCP and UDP if you've enabled both).
78+
both TCP and UDP TURN traffic)
5679

57-
6. If you've configured coturn to support TLS/DTLS, generate or
80+
7. If you've configured coturn to support TLS/DTLS, generate or
5881
import your private key and certificate.
5982

60-
7. Start the turn server::
83+
8. Start the turn server::
6184
6285
bin/turnserver -o
6386

@@ -83,12 +106,19 @@ Your home server configuration file needs the following extra keys:
83106
to refresh credentials. The TURN REST API specification recommends
84107
one day (86400000).
85108

109+
4. "turn_allow_guests": Whether to allow guest users to use the TURN
110+
server. This is enabled by default, as otherwise VoIP will not
111+
work reliably for guests. However, it does introduce a security risk
112+
as it lets guests connect to arbitrary endpoints without having gone
113+
through a CAPTCHA or similar to register a real account.
114+
86115
As an example, here is the relevant section of the config file for
87116
matrix.org::
88117

89118
turn_uris: [ "turn:turn.matrix.org:3478?transport=udp", "turn:turn.matrix.org:3478?transport=tcp" ]
90119
turn_shared_secret: n0t4ctuAllymatr1Xd0TorgSshar3d5ecret4obvIousreAsons
91120
turn_user_lifetime: 86400000
121+
turn_allow_guests: True
92122

93123
Now, restart synapse::
94124

scripts-dev/nuke-room-from-db.sh

+33-10
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,39 @@
99
ROOMID="$1"
1010

1111
sqlite3 homeserver.db <<EOF
12-
DELETE FROM context_depth WHERE context = '$ROOMID';
13-
DELETE FROM current_state WHERE context = '$ROOMID';
14-
DELETE FROM feedback WHERE room_id = '$ROOMID';
15-
DELETE FROM messages WHERE room_id = '$ROOMID';
16-
DELETE FROM pdu_backward_extremities WHERE context = '$ROOMID';
17-
DELETE FROM pdu_edges WHERE context = '$ROOMID';
18-
DELETE FROM pdu_forward_extremities WHERE context = '$ROOMID';
19-
DELETE FROM pdus WHERE context = '$ROOMID';
20-
DELETE FROM room_data WHERE room_id = '$ROOMID';
12+
DELETE FROM event_forward_extremities WHERE room_id = '$ROOMID';
13+
DELETE FROM event_backward_extremities WHERE room_id = '$ROOMID';
14+
DELETE FROM event_edges WHERE room_id = '$ROOMID';
15+
DELETE FROM room_depth WHERE room_id = '$ROOMID';
16+
DELETE FROM state_forward_extremities WHERE room_id = '$ROOMID';
17+
DELETE FROM events WHERE room_id = '$ROOMID';
18+
DELETE FROM event_json WHERE room_id = '$ROOMID';
19+
DELETE FROM state_events WHERE room_id = '$ROOMID';
20+
DELETE FROM current_state_events WHERE room_id = '$ROOMID';
2121
DELETE FROM room_memberships WHERE room_id = '$ROOMID';
22+
DELETE FROM feedback WHERE room_id = '$ROOMID';
23+
DELETE FROM topics WHERE room_id = '$ROOMID';
24+
DELETE FROM room_names WHERE room_id = '$ROOMID';
2225
DELETE FROM rooms WHERE room_id = '$ROOMID';
23-
DELETE FROM state_pdus WHERE context = '$ROOMID';
26+
DELETE FROM room_hosts WHERE room_id = '$ROOMID';
27+
DELETE FROM room_aliases WHERE room_id = '$ROOMID';
28+
DELETE FROM state_groups WHERE room_id = '$ROOMID';
29+
DELETE FROM state_groups_state WHERE room_id = '$ROOMID';
30+
DELETE FROM receipts_graph WHERE room_id = '$ROOMID';
31+
DELETE FROM receipts_linearized WHERE room_id = '$ROOMID';
32+
DELETE FROM event_search_content WHERE c1room_id = '$ROOMID';
33+
DELETE FROM guest_access WHERE room_id = '$ROOMID';
34+
DELETE FROM history_visibility WHERE room_id = '$ROOMID';
35+
DELETE FROM room_tags WHERE room_id = '$ROOMID';
36+
DELETE FROM room_tags_revisions WHERE room_id = '$ROOMID';
37+
DELETE FROM room_account_data WHERE room_id = '$ROOMID';
38+
DELETE FROM event_push_actions WHERE room_id = '$ROOMID';
39+
DELETE FROM local_invites WHERE room_id = '$ROOMID';
40+
DELETE FROM pusher_throttle WHERE room_id = '$ROOMID';
41+
DELETE FROM event_reports WHERE room_id = '$ROOMID';
42+
DELETE FROM public_room_list_stream WHERE room_id = '$ROOMID';
43+
DELETE FROM stream_ordering_to_exterm WHERE room_id = '$ROOMID';
44+
DELETE FROM event_auth WHERE room_id = '$ROOMID';
45+
DELETE FROM appservice_room_list WHERE room_id = '$ROOMID';
46+
VACUUM;
2447
EOF

scripts/synapse_port_db

+1-3
Original file line numberDiff line numberDiff line change
@@ -447,9 +447,7 @@ class Porter(object):
447447

448448
postgres_tables = yield self.postgres_store._simple_select_onecol(
449449
table="information_schema.tables",
450-
keyvalues={
451-
"table_schema": "public",
452-
},
450+
keyvalues={},
453451
retcol="distinct table_name",
454452
)
455453

synapse/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@
1616
""" This is a reference implementation of a Matrix home server.
1717
"""
1818

19-
__version__ = "0.19.3"
19+
__version__ = "0.20.0-rc1"

synapse/app/synctl.py

+45-5
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,48 @@
2323
import subprocess
2424
import sys
2525
import yaml
26+
import errno
27+
import time
2628

2729
SYNAPSE = [sys.executable, "-B", "-m", "synapse.app.homeserver"]
2830

2931
GREEN = "\x1b[1;32m"
32+
YELLOW = "\x1b[1;33m"
3033
RED = "\x1b[1;31m"
3134
NORMAL = "\x1b[m"
3235

3336

37+
def pid_running(pid):
38+
try:
39+
os.kill(pid, 0)
40+
return True
41+
except OSError, err:
42+
if err.errno == errno.EPERM:
43+
return True
44+
return False
45+
46+
3447
def write(message, colour=NORMAL, stream=sys.stdout):
3548
if colour == NORMAL:
3649
stream.write(message + "\n")
3750
else:
3851
stream.write(colour + message + NORMAL + "\n")
3952

4053

54+
def abort(message, colour=RED, stream=sys.stderr):
55+
write(message, colour, stream)
56+
sys.exit(1)
57+
58+
4159
def start(configfile):
4260
write("Starting ...")
4361
args = SYNAPSE
4462
args.extend(["--daemonize", "-c", configfile])
4563

4664
try:
4765
subprocess.check_call(args)
48-
write("started synapse.app.homeserver(%r)" % (configfile,), colour=GREEN)
66+
write("started synapse.app.homeserver(%r)" %
67+
(configfile,), colour=GREEN)
4968
except subprocess.CalledProcessError as e:
5069
write(
5170
"error starting (exit code: %d); see above for logs" % e.returncode,
@@ -76,8 +95,16 @@ def start_worker(app, configfile, worker_configfile):
7695
def stop(pidfile, app):
7796
if os.path.exists(pidfile):
7897
pid = int(open(pidfile).read())
79-
os.kill(pid, signal.SIGTERM)
80-
write("stopped %s" % (app,), colour=GREEN)
98+
try:
99+
os.kill(pid, signal.SIGTERM)
100+
write("stopped %s" % (app,), colour=GREEN)
101+
except OSError, err:
102+
if err.errno == errno.ESRCH:
103+
write("%s not running" % (app,), colour=YELLOW)
104+
elif err.errno == errno.EPERM:
105+
abort("Cannot stop %s: Operation not permitted" % (app,))
106+
else:
107+
abort("Cannot stop %s: Unknown error" % (app,))
81108

82109

83110
Worker = collections.namedtuple("Worker", [
@@ -175,7 +202,8 @@ def main():
175202
worker_app = worker_config["worker_app"]
176203
worker_pidfile = worker_config["worker_pid_file"]
177204
worker_daemonize = worker_config["worker_daemonize"]
178-
assert worker_daemonize # TODO print something more user friendly
205+
assert worker_daemonize, "In config %r: expected '%s' to be True" % (
206+
worker_configfile, "worker_daemonize")
179207
worker_cache_factor = worker_config.get("synctl_cache_factor")
180208
workers.append(Worker(
181209
worker_app, worker_configfile, worker_pidfile, worker_cache_factor,
@@ -190,7 +218,19 @@ def main():
190218
if start_stop_synapse:
191219
stop(pidfile, "synapse.app.homeserver")
192220

193-
# TODO: Wait for synapse to actually shutdown before starting it again
221+
# Wait for synapse to actually shutdown before starting it again
222+
if action == "restart":
223+
running_pids = []
224+
if start_stop_synapse and os.path.exists(pidfile):
225+
running_pids.append(int(open(pidfile).read()))
226+
for worker in workers:
227+
if os.path.exists(worker.pidfile):
228+
running_pids.append(int(open(worker.pidfile).read()))
229+
if len(running_pids) > 0:
230+
write("Waiting for process to exit before restarting...")
231+
for running_pid in running_pids:
232+
while pid_running(running_pid):
233+
time.sleep(0.2)
194234

195235
if action == "start" or action == "restart":
196236
if start_stop_synapse:

synapse/appservice/__init__.py

+20-18
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515
from synapse.api.constants import EventTypes
16+
from synapse.util.caches.descriptors import cachedInlineCallbacks
1617

1718
from twisted.internet import defer
1819

@@ -124,29 +125,23 @@ def _check_namespaces(self, namespaces):
124125
raise ValueError(
125126
"Expected bool for 'exclusive' in ns '%s'" % ns
126127
)
127-
if not isinstance(regex_obj.get("regex"), basestring):
128+
regex = regex_obj.get("regex")
129+
if isinstance(regex, basestring):
130+
regex_obj["regex"] = re.compile(regex) # Pre-compile regex
131+
else:
128132
raise ValueError(
129133
"Expected string for 'regex' in ns '%s'" % ns
130134
)
131135
return namespaces
132136

133-
def _matches_regex(self, test_string, namespace_key, return_obj=False):
134-
if not isinstance(test_string, basestring):
135-
logger.error(
136-
"Expected a string to test regex against, but got %s",
137-
test_string
138-
)
139-
return False
140-
137+
def _matches_regex(self, test_string, namespace_key):
141138
for regex_obj in self.namespaces[namespace_key]:
142-
if re.match(regex_obj["regex"], test_string):
143-
if return_obj:
144-
return regex_obj
145-
return True
146-
return False
139+
if regex_obj["regex"].match(test_string):
140+
return regex_obj
141+
return None
147142

148143
def _is_exclusive(self, ns_key, test_string):
149-
regex_obj = self._matches_regex(test_string, ns_key, return_obj=True)
144+
regex_obj = self._matches_regex(test_string, ns_key)
150145
if regex_obj:
151146
return regex_obj["exclusive"]
152147
return False
@@ -166,7 +161,14 @@ def _matches_user(self, event, store):
166161
if not store:
167162
defer.returnValue(False)
168163

169-
member_list = yield store.get_users_in_room(event.room_id)
164+
does_match = yield self._matches_user_in_member_list(event.room_id, store)
165+
defer.returnValue(does_match)
166+
167+
@cachedInlineCallbacks(num_args=1, cache_context=True)
168+
def _matches_user_in_member_list(self, room_id, store, cache_context):
169+
member_list = yield store.get_users_in_room(
170+
room_id, on_invalidate=cache_context.invalidate
171+
)
170172

171173
# check joined member events
172174
for user_id in member_list:
@@ -219,10 +221,10 @@ def is_interested_in_user(self, user_id):
219221
)
220222

221223
def is_interested_in_alias(self, alias):
222-
return self._matches_regex(alias, ApplicationService.NS_ALIASES)
224+
return bool(self._matches_regex(alias, ApplicationService.NS_ALIASES))
223225

224226
def is_interested_in_room(self, room_id):
225-
return self._matches_regex(room_id, ApplicationService.NS_ROOMS)
227+
return bool(self._matches_regex(room_id, ApplicationService.NS_ROOMS))
226228

227229
def is_exclusive_user(self, user_id):
228230
return (

0 commit comments

Comments
 (0)