Merge branch 'master' into matthew/peeking

This commit is contained in:
Matthew Hodgson 2020-09-03 21:01:30 +01:00
commit 8712ea337a
79 changed files with 4073 additions and 1928 deletions

View file

@ -34,6 +34,9 @@ type ClientAPI struct {
// TURN options
TURN TURN `yaml:"turn"`
// Rate-limiting options
RateLimiting RateLimiting `yaml:"rate_limiting"`
}
func (c *ClientAPI) Defaults() {
@ -47,6 +50,7 @@ func (c *ClientAPI) Defaults() {
c.RecaptchaBypassSecret = ""
c.RecaptchaSiteVerifyAPI = ""
c.RegistrationDisabled = false
c.RateLimiting.Defaults()
}
func (c *ClientAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
@ -61,6 +65,7 @@ func (c *ClientAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
checkNotEmpty(configErrs, "client_api.recaptcha_siteverify_api", string(c.RecaptchaSiteVerifyAPI))
}
c.TURN.Verify(configErrs)
c.RateLimiting.Verify(configErrs)
}
type TURN struct {
@ -90,3 +95,29 @@ func (c *TURN) Verify(configErrs *ConfigErrors) {
}
}
}
type RateLimiting struct {
// Is rate limiting enabled or disabled?
Enabled bool `yaml:"enabled"`
// How many "slots" a user can occupy sending requests to a rate-limited
// endpoint before we apply rate-limiting
Threshold int64 `yaml:"threshold"`
// The cooloff period in milliseconds after a request before the "slot"
// is freed again
CooloffMS int64 `yaml:"cooloff_ms"`
}
func (r *RateLimiting) Verify(configErrs *ConfigErrors) {
if r.Enabled {
checkPositive(configErrs, "client_api.rate_limiting.threshold", r.Threshold)
checkPositive(configErrs, "client_api.rate_limiting.cooloff_ms", r.CooloffMS)
}
}
func (r *RateLimiting) Defaults() {
r.Enabled = true
r.Threshold = 5
r.CooloffMS = 500
}

View file

@ -30,13 +30,13 @@ import (
// doesn't exist
var ErrRoomNoExists = errors.New("Room does not exist")
// BuildEvent builds a Matrix event using the event builder and roomserver query
// QueryAndBuildEvent builds a Matrix event using the event builder and roomserver query
// API client provided. If also fills roomserver query API response (if provided)
// in case the function calling FillBuilder needs to use it.
// Returns ErrRoomNoExists if the state of the room could not be retrieved because
// the room doesn't exist
// Returns an error if something else went wrong
func BuildEvent(
func QueryAndBuildEvent(
ctx context.Context,
builder *gomatrixserverlib.EventBuilder, cfg *config.Global, evTime time.Time,
rsAPI api.RoomserverInternalAPI, queryRes *api.QueryLatestEventsAndStateResponse,
@ -45,11 +45,25 @@ func BuildEvent(
queryRes = &api.QueryLatestEventsAndStateResponse{}
}
ver, err := AddPrevEventsToEvent(ctx, builder, rsAPI, queryRes)
eventsNeeded, err := queryRequiredEventsForBuilder(ctx, builder, rsAPI, queryRes)
if err != nil {
// This can pass through a ErrRoomNoExists to the caller
return nil, err
}
return BuildEvent(ctx, builder, cfg, evTime, eventsNeeded, queryRes)
}
// BuildEvent builds a Matrix event from the builder and QueryLatestEventsAndStateResponse
// provided.
func BuildEvent(
ctx context.Context,
builder *gomatrixserverlib.EventBuilder, cfg *config.Global, evTime time.Time,
eventsNeeded *gomatrixserverlib.StateNeeded, queryRes *api.QueryLatestEventsAndStateResponse,
) (*gomatrixserverlib.HeaderedEvent, error) {
err := addPrevEventsToEvent(builder, eventsNeeded, queryRes)
if err != nil {
return nil, err
}
event, err := builder.Build(
evTime, cfg.ServerName, cfg.KeyID,
@ -59,23 +73,23 @@ func BuildEvent(
return nil, err
}
h := event.Headered(ver)
h := event.Headered(queryRes.RoomVersion)
return &h, nil
}
// AddPrevEventsToEvent fills out the prev_events and auth_events fields in builder
func AddPrevEventsToEvent(
// queryRequiredEventsForBuilder queries the roomserver for auth/prev events needed for this builder.
func queryRequiredEventsForBuilder(
ctx context.Context,
builder *gomatrixserverlib.EventBuilder,
rsAPI api.RoomserverInternalAPI, queryRes *api.QueryLatestEventsAndStateResponse,
) (gomatrixserverlib.RoomVersion, error) {
) (*gomatrixserverlib.StateNeeded, error) {
eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(builder)
if err != nil {
return "", fmt.Errorf("gomatrixserverlib.StateNeededForEventBuilder: %w", err)
return nil, fmt.Errorf("gomatrixserverlib.StateNeededForEventBuilder: %w", err)
}
if len(eventsNeeded.Tuples()) == 0 {
return "", errors.New("expecting state tuples for event builder, got none")
return nil, errors.New("expecting state tuples for event builder, got none")
}
// Ask the roomserver for information about this room
@ -83,17 +97,22 @@ func AddPrevEventsToEvent(
RoomID: builder.RoomID,
StateToFetch: eventsNeeded.Tuples(),
}
if err = rsAPI.QueryLatestEventsAndState(ctx, &queryReq, queryRes); err != nil {
return "", fmt.Errorf("rsAPI.QueryLatestEventsAndState: %w", err)
}
return &eventsNeeded, rsAPI.QueryLatestEventsAndState(ctx, &queryReq, queryRes)
}
// addPrevEventsToEvent fills out the prev_events and auth_events fields in builder
func addPrevEventsToEvent(
builder *gomatrixserverlib.EventBuilder,
eventsNeeded *gomatrixserverlib.StateNeeded,
queryRes *api.QueryLatestEventsAndStateResponse,
) error {
if !queryRes.RoomExists {
return "", ErrRoomNoExists
return ErrRoomNoExists
}
eventFormat, err := queryRes.RoomVersion.EventFormat()
if err != nil {
return "", fmt.Errorf("queryRes.RoomVersion.EventFormat: %w", err)
return fmt.Errorf("queryRes.RoomVersion.EventFormat: %w", err)
}
builder.Depth = queryRes.Depth
@ -103,13 +122,13 @@ func AddPrevEventsToEvent(
for i := range queryRes.StateEvents {
err = authEvents.AddEvent(&queryRes.StateEvents[i].Event)
if err != nil {
return "", fmt.Errorf("authEvents.AddEvent: %w", err)
return fmt.Errorf("authEvents.AddEvent: %w", err)
}
}
refs, err := eventsNeeded.AuthEventReferences(&authEvents)
if err != nil {
return "", fmt.Errorf("eventsNeeded.AuthEventReferences: %w", err)
return fmt.Errorf("eventsNeeded.AuthEventReferences: %w", err)
}
truncAuth, truncPrev := truncateAuthAndPrevEvents(refs, queryRes.LatestEvents)
@ -129,7 +148,7 @@ func AddPrevEventsToEvent(
builder.PrevEvents = v2PrevRefs
}
return queryRes.RoomVersion, nil
return nil
}
// truncateAuthAndPrevEvents limits the number of events we add into

View file

@ -100,6 +100,8 @@ func NewBaseDendrite(cfg *config.Dendrite, componentName string, useHTTPAPIs boo
internal.SetupHookLogging(cfg.Logging, componentName)
internal.SetupPprof()
logrus.Infof("Dendrite version %s", internal.VersionString())
closer, err := cfg.SetupTracing("Dendrite" + componentName)
if err != nil {
logrus.WithError(err).Panicf("failed to start opentracing")

26
internal/version.go Normal file
View file

@ -0,0 +1,26 @@
package internal
import "fmt"
// -ldflags "-X github.com/matrix-org/dendrite/internal.branch=master"
var branch string
// -ldflags "-X github.com/matrix-org/dendrite/internal.build=alpha"
var build string
const (
VersionMajor = 0
VersionMinor = 0
VersionPatch = 0
)
func VersionString() string {
version := fmt.Sprintf("%d.%d.%d", VersionMajor, VersionMinor, VersionPatch)
if branch != "" {
version += fmt.Sprintf("-%s", branch)
}
if build != "" {
version += fmt.Sprintf("+%s", build)
}
return version
}