croc/src/api.go

187 lines
4.5 KiB
Go
Raw Normal View History

2018-06-28 16:46:16 +02:00
package croc
2018-06-30 19:56:42 +02:00
import (
"net"
"time"
log "github.com/cihub/seelog"
2018-06-30 20:45:30 +02:00
"github.com/pkg/errors"
2018-06-30 19:56:42 +02:00
"github.com/schollz/peerdiscovery"
)
2018-06-30 14:29:22 +02:00
func init() {
SetLogLevel("debug")
}
2018-06-28 16:46:16 +02:00
// Relay initiates a relay
func (c *Croc) Relay() error {
// start relay
2018-06-30 20:14:31 +02:00
go c.startRelay()
2018-06-28 16:46:16 +02:00
// start server
2018-06-30 20:14:31 +02:00
return c.startServer()
2018-06-28 16:46:16 +02:00
}
// Send will take an existing file or folder and send it through the croc relay
2018-06-30 20:45:30 +02:00
func (c *Croc) Send(fname string, codePhrase string) (err error) {
2018-07-02 16:45:46 +02:00
log.Debugf("sending %s with compression, encryption: (%v, %v)", fname, c.UseCompression, c.UseEncryption)
2018-06-30 20:45:30 +02:00
// prepare code phrase
2018-07-01 23:50:40 +02:00
defer c.cleanup()
2018-06-30 20:45:30 +02:00
c.cs.Lock()
c.cs.channel.codePhrase = codePhrase
2018-06-30 20:59:22 +02:00
if len(codePhrase) == 0 {
2018-06-30 20:45:30 +02:00
// generate code phrase
codePhrase = getRandomName()
}
2018-06-30 20:59:22 +02:00
if len(codePhrase) < 4 {
err = errors.New("code phrase must be more than 4 characters")
c.cs.Unlock()
return
}
2018-06-30 20:45:30 +02:00
c.cs.channel.codePhrase = codePhrase
c.cs.channel.Channel = codePhrase[:3]
c.cs.channel.passPhrase = codePhrase[3:]
log.Debugf("codephrase: '%s'", codePhrase)
log.Debugf("channel: '%s'", c.cs.channel.Channel)
log.Debugf("passPhrase: '%s'", c.cs.channel.passPhrase)
channel := c.cs.channel.Channel
c.cs.Unlock()
// start peer discovery
go func() {
2018-07-01 22:43:15 +02:00
if c.NoLocal {
return
}
2018-06-30 20:45:30 +02:00
log.Debug("listening for local croc relay...")
go peerdiscovery.Discover(peerdiscovery.Settings{
Limit: 1,
2018-07-01 21:47:34 +02:00
TimeLimit: 600 * time.Second,
Delay: 50 * time.Millisecond,
2018-07-02 05:46:25 +02:00
Payload: []byte(codePhrase[:3]),
2018-06-30 20:45:30 +02:00
})
}()
if len(fname) == 0 {
err = errors.New("must include filename")
return
}
err = c.processFile(fname)
if err != nil {
return
}
2018-06-30 19:56:42 +02:00
// start relay for listening
2018-07-01 21:46:43 +02:00
type runInfo struct {
err error
bothConnected bool
}
runClientError := make(chan runInfo, 2)
2018-06-30 20:01:00 +02:00
go func() {
2018-07-01 22:43:15 +02:00
if c.NoLocal {
return
}
2018-06-30 20:21:54 +02:00
d := Init()
2018-06-30 20:14:31 +02:00
d.ServerPort = "8140"
d.TcpPorts = []string{"27140", "27141"}
go d.startRelay()
go d.startServer()
2018-07-01 23:53:35 +02:00
time.Sleep(100 * time.Millisecond)
2018-07-01 21:46:43 +02:00
ce := Init()
ce.WebsocketAddress = "ws://127.0.0.1:8140"
2018-06-30 21:04:07 +02:00
// copy over the information
2018-06-30 21:02:42 +02:00
c.cs.Lock()
2018-07-01 21:46:43 +02:00
ce.cs.Lock()
ce.cs.channel.codePhrase = codePhrase
ce.cs.channel.Channel = codePhrase[:3]
ce.cs.channel.passPhrase = codePhrase[3:]
ce.cs.channel.fileMetaData = c.cs.channel.fileMetaData
ce.crocFile = c.crocFile
ce.crocFileEncrypted = ce.crocFileEncrypted
ce.isLocal = true
2018-07-01 21:46:43 +02:00
ce.cs.Unlock()
2018-06-30 21:02:42 +02:00
c.cs.Unlock()
2018-07-02 05:43:02 +02:00
defer func() {
// delete croc files
ce.cleanup()
}()
2018-07-01 21:46:43 +02:00
var ri runInfo
ri.err = ce.client(0, channel)
ri.bothConnected = ce.bothConnected
runClientError <- ri
2018-06-30 20:01:00 +02:00
}()
2018-06-30 19:56:42 +02:00
2018-06-30 20:21:54 +02:00
// start main client
go func() {
2018-07-01 22:43:15 +02:00
if c.LocalOnly {
return
}
2018-07-01 21:46:43 +02:00
var ri runInfo
ri.err = c.client(0, channel)
ri.bothConnected = c.bothConnected
2018-07-01 22:43:15 +02:00
runClientError <- ri
2018-06-30 20:21:54 +02:00
}()
2018-07-01 21:46:43 +02:00
var ri runInfo
ri = <-runClientError
2018-07-01 22:43:15 +02:00
if ri.bothConnected || c.LocalOnly || c.NoLocal {
2018-07-01 21:49:50 +02:00
return ri.err
2018-07-01 18:23:15 +02:00
}
2018-07-01 21:46:43 +02:00
ri = <-runClientError
return ri.err
2018-06-28 16:46:16 +02:00
}
// Receive will receive something through the croc relay
2018-06-30 20:45:30 +02:00
func (c *Croc) Receive(codePhrase string) (err error) {
2018-07-01 23:50:40 +02:00
defer c.cleanup()
2018-07-04 17:43:30 +02:00
log.Debugf("receiving with code phrase: %s", codePhrase)
2018-07-01 22:43:15 +02:00
if !c.NoLocal {
// try to discovery codephrase and server through peer network
discovered, errDiscover := peerdiscovery.Discover(peerdiscovery.Settings{
Limit: 1,
2018-07-03 15:55:06 +02:00
TimeLimit: 300 * time.Millisecond,
2018-07-01 22:43:15 +02:00
Delay: 50 * time.Millisecond,
2018-07-03 15:55:06 +02:00
Payload: []byte("checking"),
2018-07-01 22:43:15 +02:00
})
if errDiscover != nil {
log.Debug(errDiscover)
}
if len(discovered) > 0 {
log.Debugf("discovered %s on %s", discovered[0].Payload, discovered[0].Address)
_, connectTimeout := net.DialTimeout("tcp", discovered[0].Address+":27140", 1*time.Second)
if connectTimeout == nil {
log.Debug("connected")
c.WebsocketAddress = "ws://" + discovered[0].Address + ":8140"
c.isLocal = true
2018-07-01 22:43:15 +02:00
log.Debug(discovered[0].Address)
2018-07-02 04:30:27 +02:00
// codePhrase = string(discovered[0].Payload)
2018-07-01 22:43:15 +02:00
} else {
log.Debug("but could not connect to ports")
}
2018-06-30 20:01:00 +02:00
} else {
2018-07-01 22:43:15 +02:00
log.Debug("discovered no peers")
2018-06-30 19:56:42 +02:00
}
}
2018-06-30 20:59:22 +02:00
// prepare codephrase
c.cs.Lock()
if len(codePhrase) == 0 {
// prompt codephrase
codePhrase = promptCodePhrase()
}
if len(codePhrase) < 4 {
err = errors.New("code phrase must be more than 4 characters")
c.cs.Unlock()
return
}
c.cs.channel.codePhrase = codePhrase
c.cs.channel.Channel = codePhrase[:3]
c.cs.channel.passPhrase = codePhrase[3:]
log.Debugf("codephrase: '%s'", codePhrase)
log.Debugf("channel: '%s'", c.cs.channel.Channel)
log.Debugf("passPhrase: '%s'", c.cs.channel.passPhrase)
channel := c.cs.channel.Channel
c.cs.Unlock()
2018-06-30 20:45:30 +02:00
return c.client(1, channel)
2018-06-28 16:46:16 +02:00
}