oficina / meet Public

Clone
git clone https://amadan.net/oficina/meet

Plain git — no account needed to clone.

Download

Download this file

1package hub
2
3import (
4 "context"
5 "errors"
6)
7
8// ErrNotFanout is a Fanout of a type that is targeted or server-raised.
9var ErrNotFanout = errors.New("hub: not a fan-out type")
10
11// Fanout is §4.3's chat and share: an admitted peer to every other
12// admitted peer, the envelope rebuilt from the sender's participation so
13// from and name can never be forged, nothing ringed or stored (§6).
14// The sender's authority is §2.5's last row, exactly as Relay's: a
15// member-kind participation re-derives standing first (§15.12), and one
16// whose standing is gone is ended here with lost{standing} and answered
17// ErrNotYours; a guest never consults standing at all (ruling 14).
18func (h *Hub) Fanout(ctx context.Context, sqid, session string, from PeerID, m Message) error {
19 if m.Type != TypeChat && m.Type != TypeShare {
20 return ErrNotFanout
21 }
22 gone, err := h.memberStandingGone(ctx, sqid, session, from, true)
23 if err != nil {
24 return err
25 }
26 if gone {
27 return ErrNotYours
28 }
29 h.mu.Lock()
30 defer h.mu.Unlock()
31 r, ok := h.rooms[sqid]
32 if !ok {
33 return ErrUnknownPeer
34 }
35 p, found := h.findLocked(sqid, session, from)
36 if !found {
37 return ErrUnknownPeer
38 }
39 if !p.Admitted {
40 return ErrNotAdmitted
41 }
42 out := Message{Type: m.Type, From: p.Peer, Name: p.Name, Payload: m.Payload}
43 h.broadcastLocked(r, out, func(q *Participation) bool { return q.Admitted && q.Peer != p.Peer })
44 return nil
45}
46