Merge branch 'add-receipts-2' of github.com:S7evinK/dendrite into add-receipts-2

This commit is contained in:
Till Faelligen 2020-10-21 14:55:00 +02:00
commit bcf2bcfc95
35 changed files with 432 additions and 391 deletions

View file

@ -1,89 +1,149 @@
# Dendrite 0.1.0 (2020-10-08) # Changelog
## Dendrite 0.2.0 (2020-10-20)
### Important
* This release makes breaking changes for polylith deployments, since they now use the multi-personality binary rather than separate binary files
* Users of polylith deployments should revise their setups to use the new binary - see the Features section below
* This release also makes breaking changes for Docker deployments, as are now publishing images to Docker Hub in separate repositories for monolith and polylith
* New repositories are as follows: [matrixdotorg/dendrite-monolith](https://hub.docker.com/repository/docker/matrixdotorg/dendrite-monolith) and [matrixdotorg/dendrite-polylith](https://hub.docker.com/repository/docker/matrixdotorg/dendrite-polylith)
* The new `latest` tag will be updated with the latest release, and new versioned tags, e.g. `v0.2.0`, will preserve specific release versions
* [Sample Compose configs](https://github.com/matrix-org/dendrite/tree/master/build/docker) have been updated - if you are running a Docker deployment, please review the changes
* Images for the client API proxy and federation API proxy are no longer provided as they are unsupported - please use [nginx](docs/nginx/) (or another reverse proxy) instead
### Features
* Dendrite polylith deployments now use a special multi-personality binary, rather than separate binaries
* This is cleaner, builds faster and simplifies deployment
* The first command line argument states the component to run, e.g. `./dendrite-polylith-multi roomserver`
* Database migrations are now run at startup
* Invalid UTF-8 in requests is now rejected (contributed by [Pestdoktor](https://github.com/Pestdoktor))
* Fully read markers are now implemented in the client API (contributed by [Lesterpig](https://github.com/Lesterpig))
* Missing auth events are now retrieved from other servers in the room, rather than just the event origin
* `m.room.create` events are now validated properly when processing a `/send_join` response
* The roomserver now implements `KindOld` for handling historic events without them becoming forward extremity candidates, i.e. for backfilled or missing events
### Fixes
* State resolution v2 performance has been improved dramatically when dealing with large state sets
* The roomserver no longer processes outlier events if they are already known
* A SQLite locking issue in the previous events updater has been fixed
* The client API `/state` endpoint now correctly returns state after the leave event, if the user has left the room
* The client API `/createRoom` endpoint now sends cumulative state to the roomserver for the initial room events
* The federation API `/send` endpoint now correctly requests the entire room state from the roomserver when needed
* Some internal HTTP API paths have been fixed in the user API (contributed by [S7evinK](https://github.com/S7evinK))
* A race condition in the rate limiting code resulting in concurrent map writes has been fixed
* Each component now correctly starts a consumer/producer connection in monolith mode (when using Kafka)
* State resolution is no longer run for single trusted state snapshots that have been verified before
* A crash when rolling back the transaction in the latest events updater has been fixed
* Typing events are now ignored when the sender domain does not match the origin server
* Duplicate redaction entries no longer result in database errors
* Recursion has been removed from the code path for retrieving missing events
* `QueryMissingAuthPrevEvents` now returns events that have no associated state as if they are missing
* Signing key fetchers no longer ignore keys for the local domain, if retrieving a key that is not known in the local config
* Federation timeouts have been adjusted so we don't give up on remote requests so quickly
* `create-account` no longer relies on the device database (contributed by [ThatNerdyPikachu](https://github.com/ThatNerdyPikachu))
### Known issues
* Old events can incorrectly appear in `/sync` as if they are new when retrieving missing events from federated servers, causing them to appear at the bottom of the timeline in clients
## Dendrite 0.1.0 (2020-10-08)
First versioned release of Dendrite. First versioned release of Dendrite.
## Client-Server API Features ## Client-Server API Features
### Account registration and management ### Account registration and management
- Registration: By password only.
- Login: By password only. No fallback. * Registration: By password only.
- Logout: Yes. * Login: By password only. No fallback.
- Change password: Yes. * Logout: Yes.
- Link email/msisdn to account: No. * Change password: Yes.
- Deactivate account: Yes. * Link email/msisdn to account: No.
- Check if username is available: Yes. * Deactivate account: Yes.
- Account data: Yes. * Check if username is available: Yes.
- OpenID: No. * Account data: Yes.
* OpenID: No.
### Rooms ### Rooms
- Room creation: Yes, including presets.
- Joining rooms: Yes, including by alias or `?server_name=`. * Room creation: Yes, including presets.
- Event sending: Yes, including transaction IDs. * Joining rooms: Yes, including by alias or `?server_name=`.
- Aliases: Yes. * Event sending: Yes, including transaction IDs.
- Published room directory: Yes. * Aliases: Yes.
- Kicking users: Yes. * Published room directory: Yes.
- Banning users: Yes. * Kicking users: Yes.
- Inviting users: Yes, but not third-party invites. * Banning users: Yes.
- Forgetting rooms: No. * Inviting users: Yes, but not third-party invites.
- Room versions: All (v1 - v6) * Forgetting rooms: No.
- Tagging: Yes. * Room versions: All (v1 * v6)
* Tagging: Yes.
### User management ### User management
- User directory: Basic support.
- Ignoring users: No. * User directory: Basic support.
- Groups/Communities: No. * Ignoring users: No.
* Groups/Communities: No.
### Device management ### Device management
- Creating devices: Yes.
- Deleting devices: Yes. * Creating devices: Yes.
- Send-to-device messaging: Yes. * Deleting devices: Yes.
* Send-to-device messaging: Yes.
### Sync ### Sync
- Filters: Timeline limit only. Rest unimplemented.
- Deprecated `/events` and `/initialSync`: No. * Filters: Timeline limit only. Rest unimplemented.
* Deprecated `/events` and `/initialSync`: No.
### Room events ### Room events
- Typing: Yes.
- Receipts: No. * Typing: Yes.
- Read Markers: No. * Receipts: No.
- Presence: No. * Read Markers: No.
- Content repository (attachments): Yes. * Presence: No.
- History visibility: No, defaults to `joined`. * Content repository (attachments): Yes.
- Push notifications: No. * History visibility: No, defaults to `joined`.
- Event context: No. * Push notifications: No.
- Reporting content: No. * Event context: No.
* Reporting content: No.
### End-to-End Encryption ### End-to-End Encryption
- Uploading device keys: Yes.
- Downloading device keys: Yes. * Uploading device keys: Yes.
- Claiming one-time keys: Yes. * Downloading device keys: Yes.
- Querying key changes: Yes. * Claiming one-time keys: Yes.
- Cross-Signing: No. * Querying key changes: Yes.
* Cross-Signing: No.
### Misc ### Misc
- Server-side search: No.
- Guest access: Partial. * Server-side search: No.
- Room previews: No, partial support for Peeking via MSC2753. * Guest access: Partial.
- Third-Party networks: No. * Room previews: No, partial support for Peeking via MSC2753.
- Server notices: No. * Third-Party networks: No.
- Policy lists: No. * Server notices: No.
* Policy lists: No.
## Federation Features ## Federation Features
- Querying keys (incl. notary): Yes.
- Server ACLs: Yes. * Querying keys (incl. notary): Yes.
- Sending transactions: Yes. * Server ACLs: Yes.
- Joining rooms: Yes. * Sending transactions: Yes.
- Inviting to rooms: Yes, but not third-party invites. * Joining rooms: Yes.
- Leaving rooms: Yes. * Inviting to rooms: Yes, but not third-party invites.
- Content repository: Yes. * Leaving rooms: Yes.
- Backfilling / get_missing_events: Yes. * Content repository: Yes.
- Retrieving state of the room (`/state` and `/state_ids`): Yes. * Backfilling / get_missing_events: Yes.
- Public rooms: Yes. * Retrieving state of the room (`/state` and `/state_ids`): Yes.
- Querying profile data: Yes. * Public rooms: Yes.
- Device management: Yes. * Querying profile data: Yes.
- Send-to-Device messaging: Yes. * Device management: Yes.
- Querying/Claiming E2E Keys: Yes. * Send-to-Device messaging: Yes.
- Typing: Yes. * Querying/Claiming E2E Keys: Yes.
- Presence: No. * Typing: Yes.
- Receipts: No. * Presence: No.
- OpenID: No. * Receipts: No.
* OpenID: No.

View file

@ -1,4 +1,4 @@
FROM docker.io/golang:1.13.7-alpine3.11 AS builder FROM docker.io/golang:1.15-alpine AS builder
RUN apk --update --no-cache add bash build-base RUN apk --update --no-cache add bash build-base

View file

@ -1,13 +0,0 @@
FROM matrixdotorg/dendrite:latest AS base
FROM alpine:latest
ARG component=monolith
ENV entrypoint=${component}
COPY --from=base /build/bin/${component} /usr/bin
VOLUME /etc/dendrite
WORKDIR /etc/dendrite
ENTRYPOINT /usr/bin/${entrypoint} $@

View file

@ -0,0 +1,13 @@
FROM matrixdotorg/dendrite:latest AS base
FROM alpine:latest
COPY --from=base /build/bin/dendrite-monolith-server /usr/bin
COPY --from=base /build/bin/goose /usr/bin
COPY --from=base /build/bin/create-account /usr/bin
COPY --from=base /build/bin/generate-keys /usr/bin
VOLUME /etc/dendrite
WORKDIR /etc/dendrite
ENTRYPOINT ["/usr/bin/dendrite-monolith-server"]

View file

@ -0,0 +1,13 @@
FROM matrixdotorg/dendrite:latest AS base
FROM alpine:latest
COPY --from=base /build/bin/dendrite-polylith-multi /usr/bin
COPY --from=base /build/bin/goose /usr/bin
COPY --from=base /build/bin/create-account /usr/bin
COPY --from=base /build/bin/generate-keys /usr/bin
VOLUME /etc/dendrite
WORKDIR /etc/dendrite
ENTRYPOINT ["/usr/bin/dendrite-polylith-multi"]

View file

@ -2,7 +2,7 @@ version: "3.4"
services: services:
postgres: postgres:
hostname: postgres hostname: postgres
image: postgres:9.5 image: postgres:9.6
restart: always restart: always
volumes: volumes:
- ./postgres/create_db.sh:/docker-entrypoint-initdb.d/20-create_db.sh - ./postgres/create_db.sh:/docker-entrypoint-initdb.d/20-create_db.sh

View file

@ -2,9 +2,8 @@ version: "3.4"
services: services:
monolith: monolith:
hostname: monolith hostname: monolith
image: matrixdotorg/dendrite:monolith image: matrixdotorg/dendrite-monolith:latest
command: [ command: [
"--config=dendrite.yaml",
"--tls-cert=server.crt", "--tls-cert=server.crt",
"--tls-key=server.key" "--tls-key=server.key"
] ]

View file

@ -1,43 +1,18 @@
version: "3.4" version: "3.4"
services: services:
client_api_proxy:
hostname: client_api_proxy
image: matrixdotorg/dendrite:clientproxy
command: [
"--bind-address=:8008",
"--client-api-server-url=http://client_api:8071",
"--sync-api-server-url=http://sync_api:8073",
"--media-api-server-url=http://media_api:8074"
]
volumes:
- ./config:/etc/dendrite
networks:
- internal
depends_on:
- sync_api
- client_api
- media_api
ports:
- "8008:8008"
client_api: client_api:
hostname: client_api hostname: client_api
image: matrixdotorg/dendrite:clientapi image: matrixdotorg/dendrite-polylith:latest
command: [ command: clientapi
"--config=dendrite.yaml"
]
volumes: volumes:
- ./config:/etc/dendrite - ./config:/etc/dendrite
- room_server
networks: networks:
- internal - internal
media_api: media_api:
hostname: media_api hostname: media_api
image: matrixdotorg/dendrite:mediaapi image: matrixdotorg/dendrite-polylith:latest
command: [ command: mediaapi
"--config=dendrite.yaml"
]
volumes: volumes:
- ./config:/etc/dendrite - ./config:/etc/dendrite
networks: networks:
@ -45,10 +20,8 @@ services:
sync_api: sync_api:
hostname: sync_api hostname: sync_api
image: matrixdotorg/dendrite:syncapi image: matrixdotorg/dendrite-polylith:latest
command: [ command: syncapi
"--config=dendrite.yaml"
]
volumes: volumes:
- ./config:/etc/dendrite - ./config:/etc/dendrite
networks: networks:
@ -56,10 +29,8 @@ services:
room_server: room_server:
hostname: room_server hostname: room_server
image: matrixdotorg/dendrite:roomserver image: matrixdotorg/dendrite-polylith:latest
command: [ command: roomserver
"--config=dendrite.yaml"
]
volumes: volumes:
- ./config:/etc/dendrite - ./config:/etc/dendrite
networks: networks:
@ -67,40 +38,17 @@ services:
edu_server: edu_server:
hostname: edu_server hostname: edu_server
image: matrixdotorg/dendrite:eduserver image: matrixdotorg/dendrite-polylith:latest
command: [ command: eduserver
"--config=dendrite.yaml"
]
volumes: volumes:
- ./config:/etc/dendrite - ./config:/etc/dendrite
networks: networks:
- internal - internal
federation_api_proxy:
hostname: federation_api_proxy
image: matrixdotorg/dendrite:federationproxy
command: [
"--bind-address=:8448",
"--federation-api-url=http://federation_api:8072",
"--media-api-server-url=http://media_api:8074"
]
volumes:
- ./config:/etc/dendrite
depends_on:
- federation_api
- federation_sender
- media_api
networks:
- internal
ports:
- "8448:8448"
federation_api: federation_api:
hostname: federation_api hostname: federation_api
image: matrixdotorg/dendrite:federationapi image: matrixdotorg/dendrite-polylith:latest
command: [ command: federationapi
"--config=dendrite.yaml"
]
volumes: volumes:
- ./config:/etc/dendrite - ./config:/etc/dendrite
networks: networks:
@ -108,10 +56,8 @@ services:
federation_sender: federation_sender:
hostname: federation_sender hostname: federation_sender
image: matrixdotorg/dendrite:federationsender image: matrixdotorg/dendrite-polylith:latest
command: [ command: federationsender
"--config=dendrite.yaml"
]
volumes: volumes:
- ./config:/etc/dendrite - ./config:/etc/dendrite
networks: networks:
@ -119,10 +65,8 @@ services:
key_server: key_server:
hostname: key_server hostname: key_server
image: matrixdotorg/dendrite:keyserver image: matrixdotorg/dendrite-polylith:latest
command: [ command: keyserver
"--config=dendrite.yaml"
]
volumes: volumes:
- ./config:/etc/dendrite - ./config:/etc/dendrite
networks: networks:
@ -130,10 +74,8 @@ services:
signing_key_server: signing_key_server:
hostname: signing_key_server hostname: signing_key_server
image: matrixdotorg/dendrite:signingkeyserver image: matrixdotorg/dendrite-polylith:latest
command: [ command: signingkeyserver
"--config=dendrite.yaml"
]
volumes: volumes:
- ./config:/etc/dendrite - ./config:/etc/dendrite
networks: networks:
@ -141,10 +83,8 @@ services:
user_api: user_api:
hostname: user_api hostname: user_api
image: matrixdotorg/dendrite:userapi image: matrixdotorg/dendrite-polylith:latest
command: [ command: userapi
"--config=dendrite.yaml"
]
volumes: volumes:
- ./config:/etc/dendrite - ./config:/etc/dendrite
networks: networks:
@ -152,10 +92,8 @@ services:
appservice_api: appservice_api:
hostname: appservice_api hostname: appservice_api
image: matrixdotorg/dendrite:appservice image: matrixdotorg/dendrite-polylith:latest
command: [ command: appservice
"--config=dendrite.yaml"
]
volumes: volumes:
- ./config:/etc/dendrite - ./config:/etc/dendrite
networks: networks:

View file

@ -2,20 +2,11 @@
cd $(git rev-parse --show-toplevel) cd $(git rev-parse --show-toplevel)
docker build -f build/docker/Dockerfile -t matrixdotorg/dendrite:latest . TAG=${1:-latest}
docker build -t matrixdotorg/dendrite:monolith --build-arg component=dendrite-monolith-server -f build/docker/Dockerfile.component . echo "Building tag '${TAG}'"
docker build -t matrixdotorg/dendrite:appservice --build-arg component=dendrite-appservice-server -f build/docker/Dockerfile.component . docker build -f build/docker/Dockerfile -t matrixdotorg/dendrite:${TAG} .
docker build -t matrixdotorg/dendrite:clientapi --build-arg component=dendrite-client-api-server -f build/docker/Dockerfile.component .
docker build -t matrixdotorg/dendrite:clientproxy --build-arg component=client-api-proxy -f build/docker/Dockerfile.component . docker build -t matrixdotorg/dendrite-monolith:${TAG} -f build/docker/Dockerfile.monolith .
docker build -t matrixdotorg/dendrite:eduserver --build-arg component=dendrite-edu-server -f build/docker/Dockerfile.component . docker build -t matrixdotorg/dendrite-polylith:${TAG} -f build/docker/Dockerfile.polylith .
docker build -t matrixdotorg/dendrite:federationapi --build-arg component=dendrite-federation-api-server -f build/docker/Dockerfile.component .
docker build -t matrixdotorg/dendrite:federationsender --build-arg component=dendrite-federation-sender-server -f build/docker/Dockerfile.component .
docker build -t matrixdotorg/dendrite:federationproxy --build-arg component=federation-api-proxy -f build/docker/Dockerfile.component .
docker build -t matrixdotorg/dendrite:keyserver --build-arg component=dendrite-key-server -f build/docker/Dockerfile.component .
docker build -t matrixdotorg/dendrite:mediaapi --build-arg component=dendrite-media-api-server -f build/docker/Dockerfile.component .
docker build -t matrixdotorg/dendrite:roomserver --build-arg component=dendrite-room-server -f build/docker/Dockerfile.component .
docker build -t matrixdotorg/dendrite:syncapi --build-arg component=dendrite-sync-api-server -f build/docker/Dockerfile.component .
docker build -t matrixdotorg/dendrite:signingkeyserver --build-arg component=dendrite-signing-key-server -f build/docker/Dockerfile.component .
docker build -t matrixdotorg/dendrite:userapi --build-arg component=dendrite-user-api-server -f build/docker/Dockerfile.component .

View file

@ -1,17 +1,8 @@
#!/bin/bash #!/bin/bash
docker pull matrixdotorg/dendrite:monolith TAG=${1:-latest}
docker pull matrixdotorg/dendrite:appservice echo "Pulling tag '${TAG}'"
docker pull matrixdotorg/dendrite:clientapi
docker pull matrixdotorg/dendrite:clientproxy docker pull matrixdotorg/dendrite-monolith:${TAG}
docker pull matrixdotorg/dendrite:eduserver docker pull matrixdotorg/dendrite-polylith:${TAG}
docker pull matrixdotorg/dendrite:federationapi
docker pull matrixdotorg/dendrite:federationsender
docker pull matrixdotorg/dendrite:federationproxy
docker pull matrixdotorg/dendrite:keyserver
docker pull matrixdotorg/dendrite:mediaapi
docker pull matrixdotorg/dendrite:roomserver
docker pull matrixdotorg/dendrite:syncapi
docker pull matrixdotorg/dendrite:signingkeyserver
docker pull matrixdotorg/dendrite:userapi

View file

@ -1,17 +1,8 @@
#!/bin/bash #!/bin/bash
docker push matrixdotorg/dendrite:monolith TAG=${1:-latest}
docker push matrixdotorg/dendrite:appservice echo "Pushing tag '${TAG}'"
docker push matrixdotorg/dendrite:clientapi
docker push matrixdotorg/dendrite:clientproxy docker push matrixdotorg/dendrite-monolith:${TAG}
docker push matrixdotorg/dendrite:eduserver docker push matrixdotorg/dendrite-polylith:${TAG}
docker push matrixdotorg/dendrite:federationapi
docker push matrixdotorg/dendrite:federationsender
docker push matrixdotorg/dendrite:federationproxy
docker push matrixdotorg/dendrite:keyserver
docker push matrixdotorg/dendrite:mediaapi
docker push matrixdotorg/dendrite:roomserver
docker push matrixdotorg/dendrite:syncapi
docker push matrixdotorg/dendrite:signingkeyserver
docker push matrixdotorg/dendrite:userapi

View file

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
for db in account device mediaapi syncapi roomserver signingkeyserver keyserver federationsender appservice e2ekey naffka; do for db in account device mediaapi syncapi roomserver signingkeyserver keyserver federationsender appservice naffka; do
createdb -U dendrite -O dendrite dendrite_$db createdb -U dendrite -O dendrite dendrite_$db
done done

View file

@ -22,7 +22,6 @@ import (
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/userapi/storage/accounts" "github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/dendrite/userapi/storage/devices"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
) )
@ -39,7 +38,6 @@ var (
username = flag.String("username", "", "The user ID localpart to register e.g 'alice' in '@alice:localhost'.") username = flag.String("username", "", "The user ID localpart to register e.g 'alice' in '@alice:localhost'.")
password = flag.String("password", "", "Optional. The password to register with. If not specified, this account will be password-less.") password = flag.String("password", "", "Optional. The password to register with. If not specified, this account will be password-less.")
serverNameStr = flag.String("servername", "localhost", "The Matrix server domain which will form the domain part of the user ID.") serverNameStr = flag.String("servername", "localhost", "The Matrix server domain which will form the domain part of the user ID.")
accessToken = flag.String("token", "", "Optional. The desired access_token to have. If not specified, a random access_token will be made.")
) )
func main() { func main() {
@ -78,29 +76,5 @@ func main() {
os.Exit(1) os.Exit(1)
} }
deviceDB, err := devices.NewDatabase(&config.DatabaseOptions{ fmt.Println("Created account")
ConnectionString: config.DataSource(*database),
}, serverName)
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
if *accessToken == "" {
t := "token_" + *username
accessToken = &t
}
device, err := deviceDB.CreateDevice(
context.Background(), *username, nil, *accessToken, nil, "127.0.0.1", "",
)
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
fmt.Println("Created account:")
fmt.Printf("user_id = %s\n", device.UserID)
fmt.Printf("device_id = %s\n", device.ID)
fmt.Printf("access_token = %s\n", device.AccessToken)
} }

View file

@ -0,0 +1,78 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"flag"
"os"
"strings"
"github.com/matrix-org/dendrite/cmd/dendrite-polylith-multi/personalities"
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/setup"
"github.com/sirupsen/logrus"
)
type entrypoint func(base *setup.BaseDendrite, cfg *config.Dendrite)
func main() {
cfg := setup.ParseFlags(true)
component := ""
if flag.NFlag() > 0 {
component = flag.Arg(0) // ./dendrite-polylith-multi --config=... clientapi
} else if len(os.Args) > 1 {
component = os.Args[1] // ./dendrite-polylith-multi clientapi
}
components := map[string]entrypoint{
"appservice": personalities.Appservice,
"clientapi": personalities.ClientAPI,
"eduserver": personalities.EDUServer,
"federationapi": personalities.FederationAPI,
"federationsender": personalities.FederationSender,
"keyserver": personalities.KeyServer,
"mediaapi": personalities.MediaAPI,
"roomserver": personalities.RoomServer,
"signingkeyserver": personalities.SigningKeyServer,
"syncapi": personalities.SyncAPI,
"userapi": personalities.UserAPI,
}
start, ok := components[component]
if !ok {
if component == "" {
logrus.Errorf("No component specified")
logrus.Info("The first argument on the command line must be the name of the component to run")
} else {
logrus.Errorf("Unknown component %q specified", component)
}
var list []string
for c := range components {
list = append(list, c)
}
logrus.Infof("Valid components: %s", strings.Join(list, ", "))
os.Exit(1)
}
logrus.Infof("Starting %q component", component)
base := setup.NewBaseDendrite(cfg, component, false) // TODO
defer base.Close() // nolint: errcheck
start(base, cfg)
}

View file

@ -1,4 +1,4 @@
// Copyright 2018 Vector Creations Ltd // Copyright 2020 The Matrix.org Foundation C.I.C.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -12,18 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package main package personalities
import ( import (
"github.com/matrix-org/dendrite/appservice" "github.com/matrix-org/dendrite/appservice"
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/internal/setup"
) )
func main() { func Appservice(base *setup.BaseDendrite, cfg *config.Dendrite) {
cfg := setup.ParseFlags(false)
base := setup.NewBaseDendrite(cfg, "AppServiceAPI", true)
defer base.Close() // nolint: errcheck
userAPI := base.UserAPIClient() userAPI := base.UserAPIClient()
rsAPI := base.RoomserverHTTPClient() rsAPI := base.RoomserverHTTPClient()

View file

@ -1,4 +1,4 @@
// Copyright 2017 Vector Creations Ltd // Copyright 2020 The Matrix.org Foundation C.I.C.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -12,20 +12,16 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package main package personalities
import ( import (
"github.com/matrix-org/dendrite/clientapi" "github.com/matrix-org/dendrite/clientapi"
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/internal/transactions" "github.com/matrix-org/dendrite/internal/transactions"
) )
func main() { func ClientAPI(base *setup.BaseDendrite, cfg *config.Dendrite) {
cfg := setup.ParseFlags(false)
base := setup.NewBaseDendrite(cfg, "ClientAPI", true)
defer base.Close() // nolint: errcheck
accountDB := base.CreateAccountsDB() accountDB := base.CreateAccountsDB()
federation := base.CreateFederationClient() federation := base.CreateFederationClient()

View file

@ -1,3 +1,5 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
@ -10,26 +12,16 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package main package personalities
import ( import (
_ "net/http/pprof"
"github.com/matrix-org/dendrite/eduserver" "github.com/matrix-org/dendrite/eduserver"
"github.com/matrix-org/dendrite/eduserver/cache" "github.com/matrix-org/dendrite/eduserver/cache"
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/internal/setup"
"github.com/sirupsen/logrus"
) )
func main() { func EDUServer(base *setup.BaseDendrite, cfg *config.Dendrite) {
cfg := setup.ParseFlags(false)
base := setup.NewBaseDendrite(cfg, "EDUServerAPI", true)
defer func() {
if err := base.Close(); err != nil {
logrus.WithError(err).Warn("BaseDendrite close failed")
}
}()
intAPI := eduserver.NewInternalAPI(base, cache.New(), base.UserAPIClient()) intAPI := eduserver.NewInternalAPI(base, cache.New(), base.UserAPIClient())
eduserver.AddInternalRoutes(base.InternalAPIMux, intAPI) eduserver.AddInternalRoutes(base.InternalAPIMux, intAPI)

View file

@ -1,4 +1,4 @@
// Copyright 2017 Vector Creations Ltd // Copyright 2020 The Matrix.org Foundation C.I.C.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -12,18 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package main package personalities
import ( import (
"github.com/matrix-org/dendrite/federationapi" "github.com/matrix-org/dendrite/federationapi"
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/internal/setup"
) )
func main() { func FederationAPI(base *setup.BaseDendrite, cfg *config.Dendrite) {
cfg := setup.ParseFlags(false)
base := setup.NewBaseDendrite(cfg, "FederationAPI", true)
defer base.Close() // nolint: errcheck
userAPI := base.UserAPIClient() userAPI := base.UserAPIClient()
federation := base.CreateFederationClient() federation := base.CreateFederationClient()
serverKeyAPI := base.SigningKeyServerHTTPClient() serverKeyAPI := base.SigningKeyServerHTTPClient()

View file

@ -1,4 +1,4 @@
// Copyright 2017 Vector Creations Ltd // Copyright 2020 The Matrix.org Foundation C.I.C.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -12,18 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package main package personalities
import ( import (
"github.com/matrix-org/dendrite/federationsender" "github.com/matrix-org/dendrite/federationsender"
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/internal/setup"
) )
func main() { func FederationSender(base *setup.BaseDendrite, cfg *config.Dendrite) {
cfg := setup.ParseFlags(false)
base := setup.NewBaseDendrite(cfg, "FederationSender", true)
defer base.Close() // nolint: errcheck
federation := base.CreateFederationClient() federation := base.CreateFederationClient()
serverKeyAPI := base.SigningKeyServerHTTPClient() serverKeyAPI := base.SigningKeyServerHTTPClient()

View file

@ -12,18 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package main package personalities
import ( import (
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/keyserver" "github.com/matrix-org/dendrite/keyserver"
) )
func main() { func KeyServer(base *setup.BaseDendrite, cfg *config.Dendrite) {
cfg := setup.ParseFlags(false)
base := setup.NewBaseDendrite(cfg, "KeyServer", true)
defer base.Close() // nolint: errcheck
intAPI := keyserver.NewInternalAPI(&base.Cfg.KeyServer, base.CreateFederationClient()) intAPI := keyserver.NewInternalAPI(&base.Cfg.KeyServer, base.CreateFederationClient())
intAPI.SetUserAPI(base.UserAPIClient()) intAPI.SetUserAPI(base.UserAPIClient())

View file

@ -1,4 +1,4 @@
// Copyright 2017 Vector Creations Ltd // Copyright 2020 The Matrix.org Foundation C.I.C.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -12,18 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package main package personalities
import ( import (
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/mediaapi" "github.com/matrix-org/dendrite/mediaapi"
) )
func main() { func MediaAPI(base *setup.BaseDendrite, cfg *config.Dendrite) {
cfg := setup.ParseFlags(false)
base := setup.NewBaseDendrite(cfg, "MediaAPI", true)
defer base.Close() // nolint: errcheck
userAPI := base.UserAPIClient() userAPI := base.UserAPIClient()
client := base.CreateClient() client := base.CreateClient()

View file

@ -1,4 +1,4 @@
// Copyright 2017 Vector Creations Ltd // Copyright 2020 The Matrix.org Foundation C.I.C.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -12,18 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package main package personalities
import ( import (
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/roomserver" "github.com/matrix-org/dendrite/roomserver"
) )
func main() { func RoomServer(base *setup.BaseDendrite, cfg *config.Dendrite) {
cfg := setup.ParseFlags(false)
base := setup.NewBaseDendrite(cfg, "RoomServerAPI", true)
defer base.Close() // nolint: errcheck
serverKeyAPI := base.SigningKeyServerHTTPClient() serverKeyAPI := base.SigningKeyServerHTTPClient()
keyRing := serverKeyAPI.KeyRing() keyRing := serverKeyAPI.KeyRing()

View file

@ -12,18 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package main package personalities
import ( import (
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/signingkeyserver" "github.com/matrix-org/dendrite/signingkeyserver"
) )
func main() { func SigningKeyServer(base *setup.BaseDendrite, cfg *config.Dendrite) {
cfg := setup.ParseFlags(false)
base := setup.NewBaseDendrite(cfg, "SigningKeyServer", true)
defer base.Close() // nolint: errcheck
federation := base.CreateFederationClient() federation := base.CreateFederationClient()
intAPI := signingkeyserver.NewInternalAPI(&base.Cfg.SigningKeyServer, federation, base.Caches) intAPI := signingkeyserver.NewInternalAPI(&base.Cfg.SigningKeyServer, federation, base.Caches)

View file

@ -1,4 +1,4 @@
// Copyright 2017 Vector Creations Ltd // Copyright 2020 The Matrix.org Foundation C.I.C.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -12,19 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package main package personalities
import ( import (
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/syncapi" "github.com/matrix-org/dendrite/syncapi"
) )
func main() { func SyncAPI(base *setup.BaseDendrite, cfg *config.Dendrite) {
cfg := setup.ParseFlags(false)
base := setup.NewBaseDendrite(cfg, "SyncAPI", true)
defer base.Close() // nolint: errcheck
userAPI := base.UserAPIClient() userAPI := base.UserAPIClient()
federation := base.CreateFederationClient() federation := base.CreateFederationClient()

View file

@ -1,4 +1,4 @@
// Copyright 2017 Vector Creations Ltd // Copyright 2020 The Matrix.org Foundation C.I.C.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -12,18 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package main package personalities
import ( import (
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/userapi" "github.com/matrix-org/dendrite/userapi"
) )
func main() { func UserAPI(base *setup.BaseDendrite, cfg *config.Dendrite) {
cfg := setup.ParseFlags(false)
base := setup.NewBaseDendrite(cfg, "UserAPI", true)
defer base.Close() // nolint: errcheck
accountDB := base.CreateAccountsDB() accountDB := base.CreateAccountsDB()
userAPI := userapi.NewInternalAPI(accountDB, &cfg.UserAPI, cfg.Derived.ApplicationServices, base.KeyServerHTTPClient()) userAPI := userapi.NewInternalAPI(accountDB, &cfg.UserAPI, cfg.Derived.ApplicationServices, base.KeyServerHTTPClient())

View file

@ -24,7 +24,7 @@ use in production environments just yet!
Dendrite requires: Dendrite requires:
* Go 1.13 or higher * Go 1.13 or higher
* Postgres 9.5 or higher (if using Postgres databases, not needed for SQLite) * Postgres 9.6 or higher (if using Postgres databases, not needed for SQLite)
If you want to run a polylith deployment, you also need: If you want to run a polylith deployment, you also need:
@ -93,12 +93,12 @@ brew services start kafka
### SQLite database setup ### SQLite database setup
Dendrite can use the built-in SQLite database engine for small setups. Dendrite can use the built-in SQLite database engine for small setups.
The SQLite databases do not need to be preconfigured - Dendrite will The SQLite databases do not need to be pre-built - Dendrite will
create them automatically at startup. create them automatically at startup.
### Postgres database setup ### Postgres database setup
Assuming that Postgres 9.5 (or later) is installed: Assuming that Postgres 9.6 (or later) is installed:
* Create role, choosing a new password when prompted: * Create role, choosing a new password when prompted:
@ -109,7 +109,7 @@ Assuming that Postgres 9.5 (or later) is installed:
* Create the component databases: * Create the component databases:
```bash ```bash
for i in account device mediaapi syncapi roomserver signingkeyserver federationsender appservice e2ekey naffka; do for i in mediaapi syncapi roomserver signingkeyserver federationsender appservice keyserver userapi_account userapi_device naffka; do
sudo -u postgres createdb -O dendrite dendrite_$i sudo -u postgres createdb -O dendrite dendrite_$i
done done
``` ```
@ -135,8 +135,8 @@ Create config file, based on `dendrite-config.yaml`. Call it `dendrite.yaml`. Th
* The `server_name` entry to reflect the hostname of your Dendrite server * The `server_name` entry to reflect the hostname of your Dendrite server
* The `database` lines with an updated connection string based on your * The `database` lines with an updated connection string based on your
desired setup, e.g. replacing `component` with the name of the component: desired setup, e.g. replacing `database` with the name of the database:
* For Postgres: `postgres://dendrite:password@localhost/component` * For Postgres: `postgres://dendrite:password@localhost/database`
* For SQLite on disk: `file:component.db` or `file:///path/to/component.db` * For SQLite on disk: `file:component.db` or `file:///path/to/component.db`
* Postgres and SQLite can be mixed and matched. * Postgres and SQLite can be mixed and matched.
* The `use_naffka` option if using Naffka in a monolith deployment * The `use_naffka` option if using Naffka in a monolith deployment
@ -147,6 +147,10 @@ then configuring `key_perspectives` (like `matrix.org` in the sample) can
help to improve reliability considerably by allowing your homeserver to fetch help to improve reliability considerably by allowing your homeserver to fetch
public keys for dead homeservers from somewhere else. public keys for dead homeservers from somewhere else.
**WARNING:** Dendrite supports running all components from the same database in
Postgres mode, but this is **NOT** a supported configuration with SQLite. When
using SQLite, all components **MUST** use their own database file.
## Starting a monolith server ## Starting a monolith server
It is possible to use Naffka as an in-process replacement to Kafka when using It is possible to use Naffka as an in-process replacement to Kafka when using
@ -167,30 +171,17 @@ as shown below, it will also listen for HTTPS connections on port 8448.
The following contains scripts which will run all the required processes in order to point a Matrix client at Dendrite. The following contains scripts which will run all the required processes in order to point a Matrix client at Dendrite.
### Client proxy ### nginx (or other reverse proxy)
This is what Matrix clients will talk to. If you use the script below, point This is what your clients and federated hosts will talk to. It must forward
your client at `http://localhost:8008`. requests onto the correct API server based on URL:
```bash * `/_matrix/client` to the client API server
./bin/client-api-proxy \ * `/_matrix/federation` to the federation API server
--bind-address ":8008" \ * `/_matrix/key` to the federation API server
--client-api-server-url "http://localhost:7771" \ * `/_matrix/media` to the media API server
--sync-api-server-url "http://localhost:7773" \
--media-api-server-url "http://localhost:7774" \
```
### Federation proxy See `docs/nginx/polylith-sample.conf` for a sample configuration.
This is what Matrix servers will talk to. This is only required if you want
to support federation.
```bash
./bin/federation-api-proxy \
--bind-address ":8448" \
--federation-api-url "http://localhost:7772" \
--media-api-server-url "http://localhost:7774" \
```
### Client API server ### Client API server
@ -198,7 +189,7 @@ This is what implements CS API endpoints. Clients talk to this via the proxy in
order to send messages, create and join rooms, etc. order to send messages, create and join rooms, etc.
```bash ```bash
./bin/dendrite-client-api-server --config=dendrite.yaml ./bin/dendrite-polylith-multi --config=dendrite.yaml clientapi
``` ```
### Sync server ### Sync server
@ -207,7 +198,7 @@ This is what implements `/sync` requests. Clients talk to this via the proxy
in order to receive messages. in order to receive messages.
```bash ```bash
./bin/dendrite-sync-api-server --config dendrite.yaml ./bin/dendrite-polylith-multi --config=dendrite.yaml syncapi
``` ```
### Media server ### Media server
@ -216,7 +207,7 @@ This implements `/media` requests. Clients talk to this via the proxy in
order to upload and retrieve media. order to upload and retrieve media.
```bash ```bash
./bin/dendrite-media-api-server --config dendrite.yaml ./bin/dendrite-polylith-multi --config=dendrite.yaml mediaapi
``` ```
### Federation API server ### Federation API server
@ -226,7 +217,7 @@ order to send transactions. This is only required if you want to support
federation. federation.
```bash ```bash
./bin/dendrite-federation-api-server --config dendrite.yaml ./bin/dendrite-polylith-multi --config=dendrite.yaml federationapi
``` ```
### Internal components ### Internal components
@ -239,7 +230,7 @@ contacted by other components. This includes the following components.
This is what implements the room DAG. Clients do not talk to this. This is what implements the room DAG. Clients do not talk to this.
```bash ```bash
./bin/dendrite-room-server --config=dendrite.yaml ./bin/dendrite-polylith-multi --config=dendrite.yaml roomserver
``` ```
#### Federation sender #### Federation sender
@ -248,7 +239,7 @@ This sends events from our users to other servers. This is only required if
you want to support federation. you want to support federation.
```bash ```bash
./bin/dendrite-federation-sender-server --config dendrite.yaml ./bin/dendrite-polylith-multi --config=dendrite.yaml federationsender
``` ```
#### Appservice server #### Appservice server
@ -259,7 +250,7 @@ running locally. This is only required if you want to support running
application services on your homeserver. application services on your homeserver.
```bash ```bash
./bin/dendrite-appservice-server --config dendrite.yaml ./bin/dendrite-polylith-multi --config=dendrite.yaml appservice
``` ```
#### Key server #### Key server
@ -267,7 +258,7 @@ application services on your homeserver.
This manages end-to-end encryption keys for users. This manages end-to-end encryption keys for users.
```bash ```bash
./bin/dendrite-key-server --config dendrite.yaml ./bin/dendrite-polylith-multi --config=dendrite.yaml keyserver
``` ```
#### Signing key server #### Signing key server
@ -275,7 +266,7 @@ This manages end-to-end encryption keys for users.
This manages signing keys for servers. This manages signing keys for servers.
```bash ```bash
./bin/dendrite-signing-key-server --config dendrite.yaml ./bin/dendrite-polylith-multi --config=dendrite.yaml signingkeyserver
``` ```
#### EDU server #### EDU server
@ -283,7 +274,7 @@ This manages signing keys for servers.
This manages processing EDUs such as typing, send-to-device events and presence. Clients do not talk to This manages processing EDUs such as typing, send-to-device events and presence. Clients do not talk to
```bash ```bash
./bin/dendrite-edu-server --config dendrite.yaml ./bin/dendrite-polylith-multi --config=dendrite.yaml eduserver
``` ```
#### User server #### User server
@ -292,6 +283,6 @@ This manages user accounts, device access tokens and user account data,
amongst other things. amongst other things.
```bash ```bash
./bin/dendrite-user-api-server --config dendrite.yaml ./bin/dendrite-polylith-multi --config=dendrite.yaml userapi
``` ```

3
go.mod
View file

@ -22,7 +22,7 @@ require (
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4 github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4
github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3 github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3
github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd
github.com/matrix-org/gomatrixserverlib v0.0.0-20201016111718-6935c491a50b github.com/matrix-org/gomatrixserverlib v0.0.0-20201020160945-66a6d4926351
github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91 github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4 github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4
github.com/mattn/go-sqlite3 v1.14.2 github.com/mattn/go-sqlite3 v1.14.2
@ -40,6 +40,7 @@ require (
github.com/yggdrasil-network/yggdrasil-go v0.3.15-0.20201006093556-760d9a7fd5ee github.com/yggdrasil-network/yggdrasil-go v0.3.15-0.20201006093556-760d9a7fd5ee
go.uber.org/atomic v1.6.0 go.uber.org/atomic v1.6.0
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
golang.org/x/net v0.0.0-20200528225125-3c3fba18258b
gopkg.in/h2non/bimg.v1 v1.1.4 gopkg.in/h2non/bimg.v1 v1.1.4
gopkg.in/yaml.v2 v2.3.0 gopkg.in/yaml.v2 v2.3.0
) )

4
go.sum
View file

@ -569,8 +569,8 @@ github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26 h1:Hr3zjRsq2bh
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0= github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd h1:xVrqJK3xHREMNjwjljkAUaadalWc0rRbmVuQatzmgwg= github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd h1:xVrqJK3xHREMNjwjljkAUaadalWc0rRbmVuQatzmgwg=
github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s= github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
github.com/matrix-org/gomatrixserverlib v0.0.0-20201016111718-6935c491a50b h1:SnSzNB0kiGMNqG5r+uUEbxAjti3y+/+fu07GMPL9yNg= github.com/matrix-org/gomatrixserverlib v0.0.0-20201020160945-66a6d4926351 h1:Yg+fvSEvDLjMFkkE4W0e1yBTtCMVmH3tztw/RhTLPcA=
github.com/matrix-org/gomatrixserverlib v0.0.0-20201016111718-6935c491a50b/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU= github.com/matrix-org/gomatrixserverlib v0.0.0-20201020160945-66a6d4926351/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91 h1:HJ6U3S3ljJqNffYMcIeAncp5qT/i+ZMiJ2JC2F0aXP4= github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91 h1:HJ6U3S3ljJqNffYMcIeAncp5qT/i+ZMiJ2JC2F0aXP4=
github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91/go.mod h1:sjyPyRxKM5uw1nD2cJ6O2OxI6GOqyVBfNXqKjBZTBZE= github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91/go.mod h1:sjyPyRxKM5uw1nD2cJ6O2OxI6GOqyVBfNXqKjBZTBZE=
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 h1:ntrLa/8xVzeSs8vHFHK25k0C+NV74sYMJnNSg5NoSRo= github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 h1:ntrLa/8xVzeSs8vHFHK25k0C+NV74sYMJnNSg5NoSRo=

View file

@ -15,8 +15,10 @@
package setup package setup
import ( import (
"crypto/tls"
"fmt" "fmt"
"io" "io"
"net"
"net/http" "net/http"
"net/url" "net/url"
"time" "time"
@ -25,6 +27,8 @@ import (
"github.com/matrix-org/dendrite/internal/httputil" "github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/userapi/storage/accounts" "github.com/matrix-org/dendrite/userapi/storage/accounts"
@ -107,7 +111,22 @@ func NewBaseDendrite(cfg *config.Dendrite, componentName string, useHTTPAPIs boo
logrus.WithError(err).Warnf("Failed to create cache") logrus.WithError(err).Warnf("Failed to create cache")
} }
apiClient := http.Client{Timeout: time.Minute * 10} apiClient := http.Client{
Timeout: time.Minute * 10,
Transport: &http2.Transport{
AllowHTTP: true,
DialTLS: func(network, addr string, _ *tls.Config) (net.Conn, error) {
// Ordinarily HTTP/2 would expect TLS, but the remote listener is
// H2C-enabled (HTTP/2 without encryption). Overriding the DialTLS
// function with a plain Dial allows us to trick the HTTP client
// into establishing a HTTP/2 connection without TLS.
// TODO: Eventually we will want to look at authenticating and
// encrypting these internal HTTP APIs, at which point we will have
// to reconsider H2C and change all this anyway.
return net.Dial(network, addr)
},
},
}
client := http.Client{Timeout: HTTPClientTimeout} client := http.Client{Timeout: HTTPClientTimeout}
if cfg.FederationSender.Proxy.Enabled { if cfg.FederationSender.Proxy.Enabled {
client.Transport = &http.Transport{Proxy: http.ProxyURL(&url.URL{ client.Transport = &http.Transport{Proxy: http.ProxyURL(&url.URL{
@ -269,10 +288,17 @@ func (b *BaseDendrite) SetupAndServeHTTP(
internalServ := externalServ internalServ := externalServ
if internalAddr != NoListener && externalAddr != internalAddr { if internalAddr != NoListener && externalAddr != internalAddr {
// H2C allows us to accept HTTP/2 connections without TLS
// encryption. Since we don't currently require any form of
// authentication or encryption on these internal HTTP APIs,
// H2C gives us all of the advantages of HTTP/2 (such as
// stream multiplexing and avoiding head-of-line blocking)
// without enabling TLS.
internalH2S := &http2.Server{}
internalRouter = mux.NewRouter().SkipClean(true).UseEncodedPath() internalRouter = mux.NewRouter().SkipClean(true).UseEncodedPath()
internalServ = &http.Server{ internalServ = &http.Server{
Addr: string(internalAddr), Addr: string(internalAddr),
Handler: internalRouter, Handler: h2c.NewHandler(internalRouter, internalH2S),
} }
} }

View file

@ -16,7 +16,7 @@ var build string
const ( const (
VersionMajor = 0 VersionMajor = 0
VersionMinor = 1 VersionMinor = 2
VersionPatch = 0 VersionPatch = 0
VersionTag = "" // example: "rc1" VersionTag = "" // example: "rc1"
) )

View file

@ -17,6 +17,7 @@
package input package input
import ( import (
"bytes"
"context" "context"
"fmt" "fmt"
@ -26,6 +27,7 @@ import (
"github.com/matrix-org/dendrite/roomserver/state" "github.com/matrix-org/dendrite/roomserver/state"
"github.com/matrix-org/dendrite/roomserver/types" "github.com/matrix-org/dendrite/roomserver/types"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -44,6 +46,28 @@ func (r *Inputer) processRoomEvent(
headered := input.Event headered := input.Event
event := headered.Unwrap() event := headered.Unwrap()
// if we have already got this event then do not process it again, if the input kind is an outlier.
// Outliers contain no extra information which may warrant a re-processing.
if input.Kind == api.KindOutlier {
evs, err2 := r.DB.EventsFromIDs(ctx, []string{event.EventID()})
if err2 == nil && len(evs) == 1 {
// check hash matches if we're on early room versions where the event ID was a random string
idFormat, err2 := headered.RoomVersion.EventIDFormat()
if err2 == nil {
switch idFormat {
case gomatrixserverlib.EventIDFormatV1:
if bytes.Equal(event.EventReference().EventSHA256, evs[0].EventReference().EventSHA256) {
util.GetLogger(ctx).WithField("event_id", event.EventID()).Infof("Already processed event; ignoring")
return event.EventID(), nil
}
default:
util.GetLogger(ctx).WithField("event_id", event.EventID()).Infof("Already processed event; ignoring")
return event.EventID(), nil
}
}
}
}
// Check that the event passes authentication checks and work out // Check that the event passes authentication checks and work out
// the numeric IDs for the auth events. // the numeric IDs for the auth events.
isRejected := false isRejected := false

View file

@ -233,18 +233,6 @@ func (u *latestEventsUpdater) latestState() error {
if err != nil { if err != nil {
return fmt.Errorf("roomState.DifferenceBetweenStateSnapshots: %w", err) return fmt.Errorf("roomState.DifferenceBetweenStateSnapshots: %w", err)
} }
if len(u.removed) > len(u.added) {
// This really shouldn't happen.
// TODO: What is ultimately the best way to handle this situation?
logrus.Errorf(
"Invalid state delta on event %q wants to remove %d state but only add %d state (between state snapshots %d and %d)",
u.event.EventID(), len(u.removed), len(u.added), u.oldStateNID, u.newStateNID,
)
u.added = u.added[:0]
u.removed = u.removed[:0]
u.newStateNID = u.oldStateNID
return nil
}
// Also work out the state before the event removes and the event // Also work out the state before the event removes and the event
// adds. // adds.

View file

@ -70,16 +70,14 @@ func (u *LatestEventsUpdater) CurrentStateSnapshotNID() types.StateSnapshotNID {
return u.currentStateSnapshotNID return u.currentStateSnapshotNID
} }
// StorePreviousEvents implements types.RoomRecentEventsUpdater // StorePreviousEvents implements types.RoomRecentEventsUpdater - This must be called from a Writer
func (u *LatestEventsUpdater) StorePreviousEvents(eventNID types.EventNID, previousEventReferences []gomatrixserverlib.EventReference) error { func (u *LatestEventsUpdater) StorePreviousEvents(eventNID types.EventNID, previousEventReferences []gomatrixserverlib.EventReference) error {
return u.d.Writer.Do(u.d.DB, u.txn, func(txn *sql.Tx) error { for _, ref := range previousEventReferences {
for _, ref := range previousEventReferences { if err := u.d.PrevEventsTable.InsertPreviousEvent(u.ctx, u.txn, ref.EventID, ref.EventSHA256, eventNID); err != nil {
if err := u.d.PrevEventsTable.InsertPreviousEvent(u.ctx, txn, ref.EventID, ref.EventSHA256, eventNID); err != nil { return fmt.Errorf("u.d.PrevEventsTable.InsertPreviousEvent: %w", err)
return fmt.Errorf("u.d.PrevEventsTable.InsertPreviousEvent: %w", err)
}
} }
return nil }
}) return nil
} }
// IsReferenced implements types.RoomRecentEventsUpdater // IsReferenced implements types.RoomRecentEventsUpdater

View file

@ -492,15 +492,32 @@ func (d *Database) StoreEvent(
if roomInfo == nil && len(prevEvents) > 0 { if roomInfo == nil && len(prevEvents) > 0 {
return 0, types.StateAtEvent{}, nil, "", fmt.Errorf("expected room %q to exist", event.RoomID()) return 0, types.StateAtEvent{}, nil, "", fmt.Errorf("expected room %q to exist", event.RoomID())
} }
// Create an updater - NB: on sqlite this WILL create a txn as we are directly calling the shared DB form of
// GetLatestEventsForUpdate - not via the SQLiteDatabase form which has `nil` txns. This
// function only does SELECTs though so the created txn (at this point) is just a read txn like
// any other so this is fine. If we ever update GetLatestEventsForUpdate or NewLatestEventsUpdater
// to do writes however then this will need to go inside `Writer.Do`.
updater, err = d.GetLatestEventsForUpdate(ctx, *roomInfo) updater, err = d.GetLatestEventsForUpdate(ctx, *roomInfo)
if err != nil { if err != nil {
return 0, types.StateAtEvent{}, nil, "", fmt.Errorf("NewLatestEventsUpdater: %w", err) return 0, types.StateAtEvent{}, nil, "", fmt.Errorf("NewLatestEventsUpdater: %w", err)
} }
if err = updater.StorePreviousEvents(eventNID, prevEvents); err != nil { // Ensure that we atomically store prev events AND commit them. If we don't wrap StorePreviousEvents
return 0, types.StateAtEvent{}, nil, "", fmt.Errorf("updater.StorePreviousEvents: %w", err) // and EndTransaction in a writer then it's possible for a new write txn to be made between the two
// function calls which will then fail with 'database is locked'. This new write txn would HAVE to be
// something like SetRoomAlias/RemoveRoomAlias as normal input events are already done sequentially due to
// SupportsConcurrentRoomInputs() == false on sqlite, though this does not apply to setting room aliases
// as they don't go via InputRoomEvents
err = d.Writer.Do(d.DB, updater.txn, func(txn *sql.Tx) error {
if err = updater.StorePreviousEvents(eventNID, prevEvents); err != nil {
return fmt.Errorf("updater.StorePreviousEvents: %w", err)
}
succeeded := true
err = sqlutil.EndTransaction(updater, &succeeded)
return err
})
if err != nil {
return 0, types.StateAtEvent{}, nil, "", err
} }
succeeded := true
err = sqlutil.EndTransaction(updater, &succeeded)
} }
return roomNID, types.StateAtEvent{ return roomNID, types.StateAtEvent{

View file

@ -490,4 +490,5 @@ New read receipts appear in incremental v2 /sync
Outbound federation sends receipts Outbound federation sends receipts
Inbound federation rejects receipts from wrong remote Inbound federation rejects receipts from wrong remote
Should not be able to take over the room by pretending there is no PL event Should not be able to take over the room by pretending there is no PL event
Can get rooms/{roomId}/state for a departed room (SPEC-216) Can get rooms/{roomId}/state for a departed room (SPEC-216)
Users cannot set notifications powerlevel higher than their own