diff --git a/README.md b/README.md index 89c1f57..4f26ab5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # 🔀 Archat -*It is not working application yet, work in progress!* +*This application in in alpha stage, some features may not be working correctly or there may be bugs* -Simple P2P server (and client - for testing purposes only, client for end user will be written in NodeJS using Electron, soon). +Simple P2P server (and client - for testing purposes only, client for end user is written in Electron - you can +get it [there](https://github.com/DamianLaczynski/archat-client). ## Starting You can use these commands to start client and/or server: diff --git a/client/client.go b/client/client.go index bb06952..3f0aa12 100644 --- a/client/client.go +++ b/client/client.go @@ -23,7 +23,8 @@ import ( ) type InitiationInfo struct { - otherSideNick string + otherSideNick string + punchLaddrUsed *net.UDPAddr } type Context struct { @@ -144,12 +145,23 @@ func (cliCtx *Context) handleStartChatD(reqFrame cm.RFrame) (res cm.Response, er return nil, nil } - conn, err := net.Dial("udp", cliCtx.settings.UdpAddr) + raddr, err := net.ResolveUDPAddr("udp", cliCtx.settings.UdpAddr) + if err != nil { + logger.Error(err) + return nil, nil + } + + conn, err := net.DialUDP("udp", nil, raddr) + defer func() { + conn.Close() + logger.Debug("UDP 'connection' closed", "laddr", conn.LocalAddr()) + }() if err != nil { logger.Error("error udp dialing for punch", err) return nil, nil } + cliCtx.initiations[idx].punchLaddrUsed, _ = conn.LocalAddr().(*net.UDPAddr) enc := json.NewEncoder(conn) err = enc.Encode(cm.PunchRequest{PunchCode: startChatDReq.PunchCode}) @@ -159,6 +171,8 @@ func (cliCtx *Context) handleStartChatD(reqFrame cm.RFrame) (res cm.Response, er } logger.Debug("punch request sent!") + conn.Close() + logger.Debug("UDP 'connection' closed", "laddr", conn.LocalAddr()) return nil, nil } @@ -174,6 +188,56 @@ func (ctx *Context) handleChatStartFinish(reqFrame common.RFrame) (res common.Re "nick", startChatFinishReq.OtherSideNickname, "addr", startChatFinishReq.OtherSideAddress) + ctx.initiationsLock.RLock() + defer ctx.initiationsLock.RUnlock() + + idx := slices.IndexFunc(ctx.initiations, func(i InitiationInfo) bool { + return i.otherSideNick == startChatFinishReq.OtherSideNickname + }) + relatedInitiation := ctx.initiations[idx] + + logger.Debug("punch laddr used", "laddr", relatedInitiation.punchLaddrUsed) + raddr, err := net.ResolveUDPAddr("udp", startChatFinishReq.OtherSideAddress) + if err != nil { + logger.Error(err) + return nil, nil + } + logger.Debug("resolved raddr", "raddr", raddr.String()) + logger.Debug("dialing udp") + + conn, err := net.DialUDP("udp", relatedInitiation.punchLaddrUsed, raddr) + + if err != nil { + logger.Error(err) + return nil, nil + } + + logger.Debugf("dialed udp L%s<->R%s", relatedInitiation.punchLaddrUsed.String(), raddr.String()) + + go func() { + logger.Debug("waiting for message from other peer") + bb := make([]byte, 1024) + conn.SetDeadline(time.Now().Add(time.Second * 5)) + n, _, err := conn.ReadFrom(bb) + if err != nil { + logger.Error(err) + return + } + bb = bb[:n] + logger.Debug("got info from other peer", "info", string(bb)) + }() + + for i := 0; i < 5; i++ { + logger.Debugf("writing Hello to other peer") + _, err = conn.Write([]byte("Hello")) + if err != nil { + logger.Error(err) + return nil, nil + } + + time.Sleep(time.Second) + } + return nil, nil } @@ -445,7 +509,7 @@ func RunClient(settings common.ClientSettings) { cliCtx.initiationsLock.RLock() for _, i := range cliCtx.initiations { - logger.Debugf("with %s", i.otherSideNick) + logger.Debugf("with %+v", i) } cliCtx.initiationsLock.RUnlock() } else if cmdName == "startchatc" { diff --git a/server/server.go b/server/server.go index 3a4e628..62d9dcf 100644 --- a/server/server.go +++ b/server/server.go @@ -548,7 +548,11 @@ func testEcho(hdlCtx *handlerContext) { } func (ctx *serverContext) wsapiHandler(w http.ResponseWriter, r *http.Request) { - upgrader := websocket.Upgrader{} + upgrader := websocket.Upgrader{ + CheckOrigin: func(r *http.Request) bool { + return true // Allow all origins + }, + } conn, err := upgrader.Upgrade(w, r, nil)