1
1
Fork 0
mirror of https://github.com/schollz/croc.git synced 2025-10-11 13:21:00 +02:00
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:
lummie 2017-10-20 21:51:03 +01:00
parent 17a1f097c3
commit e2faa87b59
2 changed files with 720 additions and 673 deletions

View file

@ -153,6 +153,7 @@ func (c *Connection) runClient() error {
}
gotOK := false
gotResponse := false
gotConnectionInUse := false
for id := 0; id < c.NumberOfConnections; id++ {
go func(id int) {
defer wg.Done()
@ -180,69 +181,86 @@ func (c *Connection) runClient() error {
if c.IsSender { // this is a sender
logger.Debug("waiting for ok from relay")
message = receiveMessage(connection)
logger.Debug("got ok from relay")
if id == 0 {
fmt.Printf("\nSending (->%s)..\n", message)
if message == "no" {
fmt.Println("The specifed code is already in use by a sender.")
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
logger.Debug("waiting for meta data from sender")
message = receiveMessage(connection)
m := strings.Split(message, "-")
encryptedData, salt, iv, sendersAddress := m[0], m[1], m[2], m[3]
encryptedBytes, err := hex.DecodeString(encryptedData)
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)
if message == "no" {
fmt.Println("The specifed code is already in use by a receiver.")
gotConnectionInUse = true
} else {
sendMessage("ok", connection)
logger.Debug("receive file")
fmt.Printf("\n\nReceiving (<-%s)..\n", sendersAddress)
c.receiveFile(id, connection)
m := strings.Split(message, "-")
encryptedData, salt, iv, sendersAddress := m[0], m[1], m[2], m[3]
encryptedBytes, err := hex.DecodeString(encryptedData)
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)
}
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 {
return errors.New("Transfer interrupted")
}
@ -273,9 +291,6 @@ func (c *Connection) runClient() error {
} else {
fmt.Printf("\nReceived file written to %s", c.File.Name)
}
} else {
fmt.Println("File sent.")
// TODO: Add confirmation
}
return nil
}

View file

@ -14,12 +14,27 @@ import (
const MAX_NUMBER_THREADS = 8
type connectionMap struct {
reciever map[string]net.Conn
sender map[string]net.Conn
metadata map[string]string
receiver map[string]net.Conn
sender map[string]net.Conn
metadata map[string]string
potentialReceivers map[string]struct{}
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 {
connections connectionMap
Debug bool
@ -42,9 +57,10 @@ func NewRelay(flags *Flags) *Relay {
func (r *Relay) Run() {
r.connections = connectionMap{}
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.metadata = make(map[string]string)
r.connections.potentialReceivers = make(map[string]struct{})
r.connections.Unlock()
r.runServer()
}
@ -107,7 +123,12 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) {
"codePhrase": codePhrase,
})
if connectionType == "s" {
if connectionType == "s" { // sender connection
if r.connections.IsSenderConnected(key) {
sendMessage("no", connection)
return
}
logger.Debug("got sender")
r.connections.Lock()
r.connections.metadata[key] = metaData
@ -117,9 +138,9 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) {
receiversAddress := ""
for {
r.connections.RLock()
if _, ok := r.connections.reciever[key]; ok {
receiversAddress = r.connections.reciever[key].RemoteAddr().String()
logger.Debug("got reciever")
if _, ok := r.connections.receiver[key]; ok {
receiversAddress = r.connections.receiver[key].RemoteAddr().String()
logger.Debug("got receiver")
r.connections.RUnlock()
break
}
@ -131,18 +152,29 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) {
logger.Debug("preparing pipe")
r.connections.Lock()
con1 := r.connections.sender[key]
con2 := r.connections.reciever[key]
con2 := r.connections.receiver[key]
r.connections.Unlock()
logger.Debug("piping connections")
Pipe(con1, con2)
logger.Debug("done piping")
r.connections.Lock()
delete(r.connections.sender, key)
delete(r.connections.reciever, key)
delete(r.connections.receiver, key)
delete(r.connections.metadata, key)
delete(r.connections.potentialReceivers, key)
r.connections.Unlock()
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
sendersAddress := ""
for {
@ -168,7 +200,7 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) {
if consent == "ok" {
logger.Debug("got consent")
r.connections.Lock()
r.connections.reciever[key] = connection
r.connections.receiver[key] = connection
r.connections.Unlock()
}
}