github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/libkb/kex2_router.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package libkb 5 6 import ( 7 "encoding/base64" 8 "time" 9 10 "github.com/keybase/client/go/kex2" 11 ) 12 13 // KexRouter implements the kex2.MessageRouter interface. 14 type KexRouter struct { 15 MetaContextified 16 } 17 18 // NewKexRouter creates a contextified KexRouter. 19 func NewKexRouter(m MetaContext) *KexRouter { 20 return &KexRouter{ 21 MetaContextified: NewMetaContextified(m), 22 } 23 } 24 25 // Post implements Post in the kex2.MessageRouter interface. 26 func (k *KexRouter) Post(sessID kex2.SessionID, sender kex2.DeviceID, seqno kex2.Seqno, msg []byte) (err error) { 27 mctx := k.M().WithLogTag("KEXR") 28 mctx.Debug("+ KexRouter.Post(%x, %x, %d, ...)", sessID, sender, seqno) 29 defer func() { 30 mctx.Debug("- KexRouter.Post(%x, %x, %d) -> %s", sessID, sender, seqno, ErrToOk(err)) 31 }() 32 33 arg := APIArg{ 34 Endpoint: "kex2/send", 35 Args: HTTPArgs{ 36 "I": HexArg(sessID[:]), 37 "sender": HexArg(sender[:]), 38 "seqno": I{Val: int(seqno)}, 39 "msg": B64Arg(msg), 40 }, 41 } 42 mctx = mctx.BackgroundWithLogTags() 43 kexAPITimeout(&arg, time.Second*5) 44 _, err = mctx.G().API.Post(mctx, arg) 45 46 return err 47 } 48 49 type kexResp struct { 50 Msgs []struct { 51 Msg string `json:"msg"` 52 } `json:"msgs"` 53 Status AppStatus `json:"status"` 54 } 55 56 func (k *kexResp) GetAppStatus() *AppStatus { 57 return &k.Status 58 } 59 60 func kexAPITimeout(arg *APIArg, initial time.Duration) { 61 arg.RetryCount = 5 62 arg.RetryMultiplier = 1.0 63 initialMin := time.Second * 3 64 if initial < initialMin { 65 initial = initialMin 66 } 67 arg.InitialTimeout = initial 68 } 69 70 // Get implements Get in the kex2.MessageRouter interface. 71 func (k *KexRouter) Get(sessID kex2.SessionID, receiver kex2.DeviceID, low kex2.Seqno, poll time.Duration) (msgs [][]byte, err error) { 72 mctx := k.M().WithLogTag("KEXR") 73 mctx.Debug("+ KexRouter.Get(%x, %x, %d, %s)", sessID, receiver, low, poll) 74 defer func() { 75 mctx.Debug("- KexRouter.Get(%x, %x, %d, %s) -> %s (messages: %d)", sessID, receiver, low, poll, ErrToOk(err), len(msgs)) 76 }() 77 78 if poll > HTTPPollMaximum { 79 poll = HTTPPollMaximum 80 } 81 82 arg := APIArg{ 83 Endpoint: "kex2/receive", 84 Args: HTTPArgs{ 85 "I": HexArg(sessID[:]), 86 "receiver": HexArg(receiver[:]), 87 "low": I{Val: int(low)}, 88 "poll": I{Val: int(poll / time.Millisecond)}, 89 }, 90 } 91 kexAPITimeout(&arg, 2*poll) 92 var j kexResp 93 94 if err = mctx.G().API.GetDecode(mctx.BackgroundWithLogTags(), arg, &j); err != nil { 95 return nil, err 96 } 97 if j.Status.Code != SCOk { 98 return nil, AppStatusError{Code: j.Status.Code, Name: j.Status.Name, Desc: j.Status.Desc} 99 } 100 101 for _, m := range j.Msgs { 102 dec, err := base64.StdEncoding.DecodeString(m.Msg) 103 if err != nil { 104 return nil, err 105 } 106 msgs = append(msgs, dec) 107 } 108 109 return msgs, nil 110 }