2017-05-02 23:33:51 +00:00
|
|
|
package application
|
|
|
|
|
|
|
|
import (
|
2017-07-04 18:29:11 +00:00
|
|
|
"crypto/rsa"
|
|
|
|
"github.com/s-rah/go-ricochet"
|
2017-05-02 23:33:51 +00:00
|
|
|
"github.com/s-rah/go-ricochet/connection"
|
2017-12-13 19:33:35 +00:00
|
|
|
"github.com/s-rah/go-ricochet/identity"
|
2017-07-04 18:29:11 +00:00
|
|
|
"log"
|
|
|
|
"net"
|
2018-01-01 18:06:58 +00:00
|
|
|
"sync"
|
2017-05-02 23:33:51 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// RicochetApplication bundles many useful constructs that are
|
|
|
|
// likely standard in a ricochet application
|
|
|
|
type RicochetApplication struct {
|
2018-01-08 00:51:46 +00:00
|
|
|
contactManager ContactManagerInterface
|
|
|
|
privateKey *rsa.PrivateKey
|
|
|
|
l net.Listener
|
|
|
|
instances []*ApplicationInstance
|
|
|
|
lock sync.Mutex
|
|
|
|
aif ApplicationInstanceFactory
|
2017-05-02 23:33:51 +00:00
|
|
|
}
|
|
|
|
|
2018-01-08 00:51:46 +00:00
|
|
|
func (ra *RicochetApplication) Init(pk *rsa.PrivateKey, af ApplicationInstanceFactory, cm ContactManagerInterface) {
|
2017-07-04 18:29:11 +00:00
|
|
|
ra.privateKey = pk
|
2018-01-08 00:51:46 +00:00
|
|
|
ra.aif = af
|
2017-07-04 18:29:11 +00:00
|
|
|
ra.contactManager = cm
|
2018-01-01 18:06:58 +00:00
|
|
|
}
|
|
|
|
|
2017-07-04 18:29:11 +00:00
|
|
|
func (ra *RicochetApplication) handleConnection(conn net.Conn) {
|
|
|
|
rc, err := goricochet.NegotiateVersionInbound(conn)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("There was an error")
|
|
|
|
conn.Close()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
ich := connection.HandleInboundConnection(rc)
|
|
|
|
|
2017-12-13 19:33:35 +00:00
|
|
|
err = ich.ProcessAuthAsServer(identity.Initialize("", ra.privateKey), ra.contactManager.LookupContact)
|
2017-07-04 18:29:11 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Printf("There was an error")
|
|
|
|
conn.Close()
|
|
|
|
return
|
|
|
|
}
|
2018-01-02 17:23:20 +00:00
|
|
|
rc.TraceLog(true)
|
2018-01-08 00:51:46 +00:00
|
|
|
rai := ra.aif.GetApplicationInstance(rc)
|
2018-01-01 18:06:58 +00:00
|
|
|
ra.lock.Lock()
|
|
|
|
ra.instances = append(ra.instances, rai)
|
|
|
|
ra.lock.Unlock()
|
2017-07-04 18:29:11 +00:00
|
|
|
rc.Process(rai)
|
|
|
|
}
|
|
|
|
|
2018-01-08 00:51:46 +00:00
|
|
|
func (ra *RicochetApplication) Broadcast(do func(rai *ApplicationInstance)) {
|
2018-01-02 17:23:20 +00:00
|
|
|
ra.lock.Lock()
|
|
|
|
for _, rai := range ra.instances {
|
2018-01-08 00:51:46 +00:00
|
|
|
do(rai)
|
2018-01-02 17:23:20 +00:00
|
|
|
}
|
|
|
|
ra.lock.Unlock()
|
2018-01-01 18:06:58 +00:00
|
|
|
}
|
|
|
|
|
2017-11-02 23:43:11 +00:00
|
|
|
func (ra *RicochetApplication) Shutdown() {
|
|
|
|
log.Printf("Closing")
|
|
|
|
ra.l.Close()
|
|
|
|
log.Printf("Closed")
|
2017-07-04 18:39:19 +00:00
|
|
|
}
|
|
|
|
|
2017-07-04 18:29:11 +00:00
|
|
|
func (ra *RicochetApplication) Run(l net.Listener) {
|
|
|
|
if ra.privateKey == nil || ra.contactManager == nil {
|
|
|
|
return
|
|
|
|
}
|
2017-07-04 18:39:19 +00:00
|
|
|
ra.l = l
|
2017-11-02 23:43:11 +00:00
|
|
|
var err error
|
2017-07-04 18:39:19 +00:00
|
|
|
for err == nil {
|
|
|
|
conn, err := ra.l.Accept()
|
2017-07-04 18:29:11 +00:00
|
|
|
if err == nil {
|
|
|
|
go ra.handleConnection(conn)
|
2017-07-04 18:39:19 +00:00
|
|
|
} else {
|
2017-11-02 23:43:11 +00:00
|
|
|
log.Printf("Closing")
|
|
|
|
return
|
2017-07-04 18:29:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|