mirror of
https://github.com/schollz/croc.git
synced 2025-10-11 13:21:00 +02:00
Issue #25
fixed spelling connectionMap.receiver Added method to detect if sender and receivers are already connected. Added client code to correctly action "no" returned by the code being in use.
This commit is contained in:
parent
17a1f097c3
commit
e2faa87b59
2 changed files with 720 additions and 673 deletions
125
connect.go
125
connect.go
|
@ -153,6 +153,7 @@ func (c *Connection) runClient() error {
|
||||||
}
|
}
|
||||||
gotOK := false
|
gotOK := false
|
||||||
gotResponse := false
|
gotResponse := false
|
||||||
|
gotConnectionInUse := false
|
||||||
for id := 0; id < c.NumberOfConnections; id++ {
|
for id := 0; id < c.NumberOfConnections; id++ {
|
||||||
go func(id int) {
|
go func(id int) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
@ -180,69 +181,86 @@ func (c *Connection) runClient() error {
|
||||||
if c.IsSender { // this is a sender
|
if c.IsSender { // this is a sender
|
||||||
logger.Debug("waiting for ok from relay")
|
logger.Debug("waiting for ok from relay")
|
||||||
message = receiveMessage(connection)
|
message = receiveMessage(connection)
|
||||||
logger.Debug("got ok from relay")
|
if message == "no" {
|
||||||
if id == 0 {
|
fmt.Println("The specifed code is already in use by a sender.")
|
||||||
fmt.Printf("\nSending (->%s)..\n", message)
|
gotConnectionInUse = true
|
||||||
|
} else {
|
||||||
|
logger.Debug("got ok from relay")
|
||||||
|
if id == 0 {
|
||||||
|
fmt.Printf("\nSending (->%s)..\n", message)
|
||||||
|
}
|
||||||
|
// wait for pipe to be made
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
// Write data from file
|
||||||
|
logger.Debug("send file")
|
||||||
|
c.sendFile(id, connection)
|
||||||
|
fmt.Println("File sent.")
|
||||||
}
|
}
|
||||||
// wait for pipe to be made
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
|
||||||
// Write data from file
|
|
||||||
logger.Debug("send file")
|
|
||||||
c.sendFile(id, connection)
|
|
||||||
} else { // this is a receiver
|
} else { // this is a receiver
|
||||||
logger.Debug("waiting for meta data from sender")
|
logger.Debug("waiting for meta data from sender")
|
||||||
message = receiveMessage(connection)
|
message = receiveMessage(connection)
|
||||||
m := strings.Split(message, "-")
|
if message == "no" {
|
||||||
encryptedData, salt, iv, sendersAddress := m[0], m[1], m[2], m[3]
|
fmt.Println("The specifed code is already in use by a receiver.")
|
||||||
encryptedBytes, err := hex.DecodeString(encryptedData)
|
gotConnectionInUse = true
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
decryptedBytes, _ := Decrypt(encryptedBytes, c.Code, salt, iv, c.DontEncrypt)
|
|
||||||
err = json.Unmarshal(decryptedBytes, &c.File)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Debugf("meta data received: %v", c.File)
|
|
||||||
// have the main thread ask for the okay
|
|
||||||
if id == 0 {
|
|
||||||
fmt.Printf("Receiving file (%d bytes) into: %s\n", c.File.Size, c.File.Name)
|
|
||||||
var sentFileNames []string
|
|
||||||
|
|
||||||
if fileAlreadyExists(sentFileNames, c.File.Name) {
|
|
||||||
fmt.Printf("Will not overwrite file!")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
getOK := getInput("ok? (y/n): ")
|
|
||||||
if getOK == "y" {
|
|
||||||
gotOK = true
|
|
||||||
sentFileNames = append(sentFileNames, c.File.Name)
|
|
||||||
}
|
|
||||||
gotResponse = true
|
|
||||||
}
|
|
||||||
// wait for the main thread to get the okay
|
|
||||||
for limit := 0; limit < 1000; limit++ {
|
|
||||||
if gotResponse {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
|
||||||
}
|
|
||||||
if !gotOK {
|
|
||||||
sendMessage("not ok", connection)
|
|
||||||
} else {
|
} else {
|
||||||
sendMessage("ok", connection)
|
m := strings.Split(message, "-")
|
||||||
logger.Debug("receive file")
|
encryptedData, salt, iv, sendersAddress := m[0], m[1], m[2], m[3]
|
||||||
fmt.Printf("\n\nReceiving (<-%s)..\n", sendersAddress)
|
encryptedBytes, err := hex.DecodeString(encryptedData)
|
||||||
c.receiveFile(id, connection)
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
decryptedBytes, _ := Decrypt(encryptedBytes, c.Code, salt, iv, c.DontEncrypt)
|
||||||
|
err = json.Unmarshal(decryptedBytes, &c.File)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Debugf("meta data received: %v", c.File)
|
||||||
|
// have the main thread ask for the okay
|
||||||
|
if id == 0 {
|
||||||
|
fmt.Printf("Receiving file (%d bytes) into: %s\n", c.File.Size, c.File.Name)
|
||||||
|
var sentFileNames []string
|
||||||
|
|
||||||
|
if fileAlreadyExists(sentFileNames, c.File.Name) {
|
||||||
|
fmt.Printf("Will not overwrite file!")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
getOK := getInput("ok? (y/n): ")
|
||||||
|
if getOK == "y" {
|
||||||
|
gotOK = true
|
||||||
|
sentFileNames = append(sentFileNames, c.File.Name)
|
||||||
|
}
|
||||||
|
gotResponse = true
|
||||||
|
}
|
||||||
|
// wait for the main thread to get the okay
|
||||||
|
for limit := 0; limit < 1000; limit++ {
|
||||||
|
if gotResponse {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
}
|
||||||
|
if !gotOK {
|
||||||
|
sendMessage("not ok", connection)
|
||||||
|
} else {
|
||||||
|
sendMessage("ok", connection)
|
||||||
|
logger.Debug("receive file")
|
||||||
|
fmt.Printf("\n\nReceiving (<-%s)..\n", sendersAddress)
|
||||||
|
c.receiveFile(id, connection)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}(id)
|
}(id)
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
if !c.IsSender {
|
if gotConnectionInUse {
|
||||||
|
return nil // connection was in use, just quit cleanly
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsSender {
|
||||||
|
// TODO: Add confirmation
|
||||||
|
} else { // Is a Receiver
|
||||||
if !gotOK {
|
if !gotOK {
|
||||||
return errors.New("Transfer interrupted")
|
return errors.New("Transfer interrupted")
|
||||||
}
|
}
|
||||||
|
@ -273,9 +291,6 @@ func (c *Connection) runClient() error {
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("\nReceived file written to %s", c.File.Name)
|
fmt.Printf("\nReceived file written to %s", c.File.Name)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
fmt.Println("File sent.")
|
|
||||||
// TODO: Add confirmation
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
56
relay.go
56
relay.go
|
@ -14,12 +14,27 @@ import (
|
||||||
const MAX_NUMBER_THREADS = 8
|
const MAX_NUMBER_THREADS = 8
|
||||||
|
|
||||||
type connectionMap struct {
|
type connectionMap struct {
|
||||||
reciever map[string]net.Conn
|
receiver map[string]net.Conn
|
||||||
sender map[string]net.Conn
|
sender map[string]net.Conn
|
||||||
metadata map[string]string
|
metadata map[string]string
|
||||||
|
potentialReceivers map[string]struct{}
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *connectionMap) IsSenderConnected(key string) (found bool) {
|
||||||
|
c.RLock()
|
||||||
|
defer c.RUnlock()
|
||||||
|
_, found = c.sender[key]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *connectionMap) IsPotentialReceiverConnected(key string) (found bool) {
|
||||||
|
c.RLock()
|
||||||
|
defer c.RUnlock()
|
||||||
|
_, found = c.potentialReceivers[key]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
type Relay struct {
|
type Relay struct {
|
||||||
connections connectionMap
|
connections connectionMap
|
||||||
Debug bool
|
Debug bool
|
||||||
|
@ -42,9 +57,10 @@ func NewRelay(flags *Flags) *Relay {
|
||||||
func (r *Relay) Run() {
|
func (r *Relay) Run() {
|
||||||
r.connections = connectionMap{}
|
r.connections = connectionMap{}
|
||||||
r.connections.Lock()
|
r.connections.Lock()
|
||||||
r.connections.reciever = make(map[string]net.Conn)
|
r.connections.receiver = make(map[string]net.Conn)
|
||||||
r.connections.sender = make(map[string]net.Conn)
|
r.connections.sender = make(map[string]net.Conn)
|
||||||
r.connections.metadata = make(map[string]string)
|
r.connections.metadata = make(map[string]string)
|
||||||
|
r.connections.potentialReceivers = make(map[string]struct{})
|
||||||
r.connections.Unlock()
|
r.connections.Unlock()
|
||||||
r.runServer()
|
r.runServer()
|
||||||
}
|
}
|
||||||
|
@ -107,7 +123,12 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) {
|
||||||
"codePhrase": codePhrase,
|
"codePhrase": codePhrase,
|
||||||
})
|
})
|
||||||
|
|
||||||
if connectionType == "s" {
|
if connectionType == "s" { // sender connection
|
||||||
|
if r.connections.IsSenderConnected(key) {
|
||||||
|
sendMessage("no", connection)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
logger.Debug("got sender")
|
logger.Debug("got sender")
|
||||||
r.connections.Lock()
|
r.connections.Lock()
|
||||||
r.connections.metadata[key] = metaData
|
r.connections.metadata[key] = metaData
|
||||||
|
@ -117,9 +138,9 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) {
|
||||||
receiversAddress := ""
|
receiversAddress := ""
|
||||||
for {
|
for {
|
||||||
r.connections.RLock()
|
r.connections.RLock()
|
||||||
if _, ok := r.connections.reciever[key]; ok {
|
if _, ok := r.connections.receiver[key]; ok {
|
||||||
receiversAddress = r.connections.reciever[key].RemoteAddr().String()
|
receiversAddress = r.connections.receiver[key].RemoteAddr().String()
|
||||||
logger.Debug("got reciever")
|
logger.Debug("got receiver")
|
||||||
r.connections.RUnlock()
|
r.connections.RUnlock()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -131,18 +152,29 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) {
|
||||||
logger.Debug("preparing pipe")
|
logger.Debug("preparing pipe")
|
||||||
r.connections.Lock()
|
r.connections.Lock()
|
||||||
con1 := r.connections.sender[key]
|
con1 := r.connections.sender[key]
|
||||||
con2 := r.connections.reciever[key]
|
con2 := r.connections.receiver[key]
|
||||||
r.connections.Unlock()
|
r.connections.Unlock()
|
||||||
logger.Debug("piping connections")
|
logger.Debug("piping connections")
|
||||||
Pipe(con1, con2)
|
Pipe(con1, con2)
|
||||||
logger.Debug("done piping")
|
logger.Debug("done piping")
|
||||||
r.connections.Lock()
|
r.connections.Lock()
|
||||||
delete(r.connections.sender, key)
|
delete(r.connections.sender, key)
|
||||||
delete(r.connections.reciever, key)
|
delete(r.connections.receiver, key)
|
||||||
delete(r.connections.metadata, key)
|
delete(r.connections.metadata, key)
|
||||||
|
delete(r.connections.potentialReceivers, key)
|
||||||
r.connections.Unlock()
|
r.connections.Unlock()
|
||||||
logger.Debug("deleted sender and receiver")
|
logger.Debug("deleted sender and receiver")
|
||||||
} else {
|
} else { //receiver connection "r"
|
||||||
|
if r.connections.IsPotentialReceiverConnected(key) {
|
||||||
|
sendMessage("no", connection)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// add as a potential receiver
|
||||||
|
r.connections.Lock()
|
||||||
|
r.connections.potentialReceivers[key] = struct{}{}
|
||||||
|
r.connections.Unlock()
|
||||||
|
|
||||||
// wait for sender's metadata
|
// wait for sender's metadata
|
||||||
sendersAddress := ""
|
sendersAddress := ""
|
||||||
for {
|
for {
|
||||||
|
@ -168,7 +200,7 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) {
|
||||||
if consent == "ok" {
|
if consent == "ok" {
|
||||||
logger.Debug("got consent")
|
logger.Debug("got consent")
|
||||||
r.connections.Lock()
|
r.connections.Lock()
|
||||||
r.connections.reciever[key] = connection
|
r.connections.receiver[key] = connection
|
||||||
r.connections.Unlock()
|
r.connections.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue