| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | package main | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-18 22:25:59 +09:00
										 |  |  | import "errors" | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | import "fmt" | 
					
						
							| 
									
										
										
										
											2024-11-17 14:57:56 +09:00
										 |  |  | import "io" | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | import "net" | 
					
						
							| 
									
										
										
										
											2024-11-18 22:25:59 +09:00
										 |  |  | import "sync" | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | import "sync/atomic" | 
					
						
							|  |  |  | import "time" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type ServerPeerConn struct { | 
					
						
							|  |  |  | 	route *ServerRoute | 
					
						
							|  |  |  | 	conn_id uint32 | 
					
						
							|  |  |  | 	cts *ClientConn | 
					
						
							|  |  |  | 	conn *net.TCPConn | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-18 22:25:59 +09:00
										 |  |  | 	stop_chan chan bool | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 	stop_req  atomic.Bool | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 	client_peer_status_chan chan bool | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 	client_peer_started atomic.Bool | 
					
						
							|  |  |  | 	client_peer_stopped atomic.Bool | 
					
						
							|  |  |  | 	client_peer_eof atomic.Bool | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NewServerPeerConn(r *ServerRoute, c *net.TCPConn, id uint32) (*ServerPeerConn) { | 
					
						
							|  |  |  | 	var spc ServerPeerConn | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spc.route = r | 
					
						
							|  |  |  | 	spc.conn = c | 
					
						
							|  |  |  | 	spc.conn_id = id | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	spc.stop_chan = make(chan bool, 8) | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 	spc.stop_req.Store(false) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 	spc.client_peer_status_chan = make(chan bool, 8) | 
					
						
							|  |  |  | 	spc.client_peer_started.Store(false) | 
					
						
							|  |  |  | 	spc.client_peer_stopped.Store(false) | 
					
						
							|  |  |  | 	spc.client_peer_eof.Store(false) | 
					
						
							|  |  |  | fmt.Printf ("~~~~~~~~~~~~~~~ NEW SERVER PEER CONNECTION ADDED %p\n", &spc) | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 	return &spc | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-18 22:25:59 +09:00
										 |  |  | func (spc *ServerPeerConn) RunTask(wg *sync.WaitGroup) { | 
					
						
							|  |  |  | 	var pss *GuardedPacketStreamServer | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 	var n int | 
					
						
							|  |  |  | 	var buf [4096]byte | 
					
						
							|  |  |  | 	var tmr *time.Timer | 
					
						
							|  |  |  | 	var status bool | 
					
						
							|  |  |  | 	var err error = nil | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-18 22:25:59 +09:00
										 |  |  | 	defer wg.Done() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 	pss = spc.route.cts.pss | 
					
						
							|  |  |  | 	err = pss.Send(MakePeerStartedPacket(spc.route.id, spc.conn_id)) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		// TODO: include route id and conn id in the error message | 
					
						
							| 
									
										
										
										
											2024-11-17 14:57:56 +09:00
										 |  |  | 		fmt.Printf("unable to send start-pts - %s\n", err.Error()) | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 		goto done_without_stop | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tmr = time.NewTimer(2 * time.Second) // TODO: make this configurable... | 
					
						
							|  |  |  | wait_for_started: | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		select { | 
					
						
							|  |  |  | 			case status = <- spc.client_peer_status_chan: | 
					
						
							|  |  |  | 				if status { | 
					
						
							|  |  |  | 					break wait_for_started | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					// the socket must have been closed too. | 
					
						
							|  |  |  | 					goto done | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2024-11-13 23:14:43 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 			case <- tmr.C: | 
					
						
							|  |  |  | 				// connection failure, not in time | 
					
						
							|  |  |  | 				tmr.Stop() | 
					
						
							|  |  |  | 				goto done | 
					
						
							| 
									
										
										
										
											2024-11-13 23:14:43 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-18 22:25:59 +09:00
										 |  |  | 			case <- spc.stop_chan: | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 				tmr.Stop() | 
					
						
							| 
									
										
										
										
											2024-11-18 22:25:59 +09:00
										 |  |  | 				goto done | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	tmr.Stop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		n, err = spc.conn.Read(buf[:]) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 			if errors.Is(err, io.EOF) { | 
					
						
							|  |  |  | 				if pss.Send(MakePeerEofPacket(spc.route.id, spc.conn_id)) != nil { | 
					
						
							|  |  |  | 					fmt.Printf("unable to report data - %s\n", err.Error()) | 
					
						
							|  |  |  | 					goto done | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				goto wait_for_stopped | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2024-11-17 14:57:56 +09:00
										 |  |  | 				fmt.Printf("read error - %s\n", err.Error()) | 
					
						
							| 
									
										
										
										
											2024-11-18 22:25:59 +09:00
										 |  |  | 				goto done | 
					
						
							| 
									
										
										
										
											2024-11-17 14:57:56 +09:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		err = pss.Send(MakePeerDataPacket(spc.route.id, spc.conn_id, buf[:n])) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			// TODO: include route id and conn id in the error message | 
					
						
							| 
									
										
										
										
											2024-11-17 14:57:56 +09:00
										 |  |  | 			fmt.Printf("unable to send data - %s\n", err.Error()) | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 			goto done; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-18 22:25:59 +09:00
										 |  |  | wait_for_stopped: | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 	for { | 
					
						
							|  |  |  | fmt.Printf ("******************* Waiting for peer Stop\n") | 
					
						
							|  |  |  | 		select { | 
					
						
							|  |  |  | 			case status = <- spc.client_peer_status_chan: // something not right... may use a different channel for closing... | 
					
						
							|  |  |  | 				goto done | 
					
						
							|  |  |  | 			case <- spc.stop_chan: | 
					
						
							|  |  |  | 				goto done | 
					
						
							| 
									
										
										
										
											2024-11-18 22:25:59 +09:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 	} | 
					
						
							|  |  |  | fmt.Printf ("******************* Sending peer stopped\n") | 
					
						
							|  |  |  | 	if pss.Send(MakePeerStoppedPacket(spc.route.id, spc.conn_id)) != nil { | 
					
						
							|  |  |  | 		fmt.Printf("unable to report data - %s\n", err.Error()) | 
					
						
							|  |  |  | 		goto done | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-11-18 22:25:59 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | done: | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 	if pss.Send(MakePeerStoppedPacket(spc.route.id, spc.conn_id)) != nil { | 
					
						
							|  |  |  | 		fmt.Printf("unable to report data - %s\n", err.Error()) | 
					
						
							|  |  |  | 		// nothing much to do about the failure of sending this | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | done_without_stop: | 
					
						
							| 
									
										
										
										
											2024-11-17 14:57:56 +09:00
										 |  |  | 	fmt.Printf("SPC really ending..................\n") | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 	spc.ReqStop() | 
					
						
							|  |  |  | 	spc.route.RemoveServerPeerConn(spc) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (spc *ServerPeerConn) ReqStop() { | 
					
						
							|  |  |  | 	if spc.stop_req.CompareAndSwap(false, true) { | 
					
						
							| 
									
										
										
										
											2024-11-18 22:25:59 +09:00
										 |  |  | 		spc.stop_chan <- true | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if spc.client_peer_started.CompareAndSwap(false, true) { | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 			spc.client_peer_status_chan <- false | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 		if spc.client_peer_stopped.CompareAndSwap(false, true) { | 
					
						
							|  |  |  | 			spc.client_peer_status_chan <- false | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		spc.conn.Close() // to abort the main Recv() loop | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (spc *ServerPeerConn) ReportEvent (event_type PACKET_KIND, event_data []byte) error { | 
					
						
							| 
									
										
										
										
											2024-11-13 23:14:43 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 	switch event_type { | 
					
						
							|  |  |  | 		case PACKET_KIND_PEER_STARTED: | 
					
						
							| 
									
										
										
										
											2024-11-17 14:57:56 +09:00
										 |  |  | fmt.Printf("******************* AAAAAAAAAAAAAAAAAAAaaa\n") | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 			if spc.client_peer_started.CompareAndSwap(false, true) { | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 				spc.client_peer_status_chan <- true | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2024-11-13 23:14:43 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 		case PACKET_KIND_PEER_STOPPED: | 
					
						
							| 
									
										
										
										
											2024-11-17 14:57:56 +09:00
										 |  |  | fmt.Printf("******************* BBBBBBBBBBBBBBBBBBBBBBBB\n") | 
					
						
							|  |  |  | 			// this event needs to close on the server-side peer connection. | 
					
						
							|  |  |  | 			// sending false to the client_peer_status_chan isn't good enough to break | 
					
						
							|  |  |  | 			// the Recv loop in RunTask(). | 
					
						
							|  |  |  | 			spc.ReqStop() | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 		case PACKET_KIND_PEER_EOF: | 
					
						
							|  |  |  | fmt.Printf("******************* BBBBBBBBBBBBBBBBBBBBBBBB CLIENT PEER EOF\n") | 
					
						
							|  |  |  | 			// the client-side peer is not supposed to send data any more | 
					
						
							|  |  |  | 			if spc.client_peer_eof.CompareAndSwap(false, true) { | 
					
						
							|  |  |  | 				spc.conn.CloseWrite() | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 		case PACKET_KIND_PEER_DATA: | 
					
						
							| 
									
										
										
										
											2024-11-17 14:57:56 +09:00
										 |  |  | fmt.Printf("******************* CCCCCCCCCCCCCCCCCCCCCCCccc\n") | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 			if spc.client_peer_eof.Load() == false { | 
					
						
							|  |  |  | 				var err error | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-20 00:31:14 +09:00
										 |  |  | 				_, err = spc.conn.Write(event_data) | 
					
						
							|  |  |  | 				if err != nil { | 
					
						
							|  |  |  | 					// TODO: logging | 
					
						
							|  |  |  | 					fmt.Printf ("WARNING - failed to write data from %s to %s\n", spc.route.cts.caddr, spc.conn.RemoteAddr().String()) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				// protocol error. the client must not relay more data from the client-side peer after EOF. | 
					
						
							|  |  |  | 				fmt.Printf ("WARNING - broken client - redundant data from %s to %s\n", spc.route.cts.caddr, spc.conn.RemoteAddr().String()) | 
					
						
							| 
									
										
										
										
											2024-11-12 22:59:37 +09:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			// ignore all other events | 
					
						
							|  |  |  | 			// TODO: produce warning in debug mode | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } |