func main() { target_addr := flag.String("target", default_target, "The partner to exchange latency measurement packets with") local_addr := protocols.ParseServerFlags("0.0.0.0", 6060) server, err := NewServer(local_addr) golib.Checkerr(err) client, err := NewClientFor(*target_addr) golib.Checkerr(err) measureLatency := golib.NewLoopTask("sending latency packets", func(stop golib.StopChan) { err := client.SendMeasureLatency() if err != nil { log.Println("Error sending Latency packet:", err) } select { case <-time.After(1 * time.Second): case <-stop: } }) log.Println("Listening to Latency on " + local_addr + ", sending to: " + *target_addr) log.Println("Press Ctrl-C to close") golib.NewTaskGroup( server, measureLatency, &golib.NoopTask{golib.ExternalInterrupt(), "external interrupt"}, ).WaitAndExit() }
func startProxies(proxy_port, rtp_port int) (string, int) { proxy_ip := rtp_ip if !pretend_proxy { if use_pcp { proxy_ip = pcpProxyIp() client, err := pcp.NewClientFor(pcp_url) client.SetTimeout(time.Duration(client_timeout * float64(time.Second))) golib.Checkerr(err) log.Printf("Starting external proxies using %v\n", client) makeProxyPCP(client, proxy_port, rtp_port) makeProxyPCP(client, proxy_port+1, rtp_port+1) tasks.AddNamed("proxy", &golib.CleanupTask{Description: "stop proxies", Cleanup: func() { closeProxyPCP(client, proxy_port, rtp_port) closeProxyPCP(client, proxy_port+1, rtp_port+1) golib.Printerr(client.Close()) }}) } else { proxy1 := makeProxy(proxy_port, rtp_port) proxy2 := makeProxy(proxy_port+1, rtp_port+1) statistics = append(statistics, proxy1.Stats, proxy2.Stats) tasks.AddNamed("proxy", proxy1, proxy2, &golib.CleanupTask{ Description: "print proxy errors", Cleanup: func() { if proxy1.Err != nil { log.Printf("Proxy %v error: %v\n", proxy_port, proxy1.Err) } if proxy2.Err != nil { log.Printf("Proxy %v error: %v\n", proxy_port+1, proxy2.Err) } }}) } } return proxy_ip, proxy_port }
func makeProxy(listenPort, targetPort int) *proxies.UdpProxy { // Local proxy: use same IP as for RTP traffic listen := net.JoinHostPort(rtp_ip, strconv.Itoa(listenPort)) target := net.JoinHostPort(rtp_ip, strconv.Itoa(targetPort)) p, err := proxies.NewUdpProxy(listen, target) golib.Checkerr(err) log.Printf("UDP proxy started: %s\n", p) return p }
func main() { payloadSize := flag.Uint("payload", 0, "Additional payload to append to Load packets") amp_addr := protocols.ParseServerFlags("0.0.0.0", 7770) proto, err := protocols.NewProtocol("AMP/Load", amp.Protocol, amp_control.Protocol, ping.Protocol, heartbeat.Protocol) golib.Checkerr(err) server, err := protocols.NewServer(amp_addr, proto) golib.Checkerr(err) loadServer, err := RegisterLoadServer(server) golib.Checkerr(err) loadServer.PayloadSize = *payloadSize go printErrors(server) log.Println("Listening:", server) log.Println("Press Ctrl-C to close") golib.NewTaskGroup( server, &golib.NoopTask{golib.ExternalInterrupt(), "external interrupt"}, ).WaitAndExit() }
func main() { proxies.UdpProxyFlags() pcp_addr := protocols.ParseServerFlags("0.0.0.0", 7778) proto, err := protocols.NewProtocol("PCP", pcp.Protocol, ping.Protocol, heartbeat.Protocol) golib.Checkerr(err) server, err := protocols.NewServer(pcp_addr, proto) golib.Checkerr(err) proxy, err := proxies.RegisterPcpProxy(server) golib.Checkerr(err) go printPcpErrors(proxy) proxy.ProxyStartedCallback = proxyStarted proxy.ProxyStoppedCallback = proxyStopped log.Println("Listening:", server) log.Println("Press Ctrl-C to close") golib.NewTaskGroup( server, &golib.NoopTask{golib.ExternalInterrupt(), "external interrupt"}, ).WaitAndExit() }
func startStream(target_ip string, rtp_port int) { if use_amp { log.Println("Starting stream using AMP at", amp_url) client, err := amp.NewClientFor(amp_url) golib.Checkerr(err) client.SetTimeout(time.Duration(client_timeout * float64(time.Second))) golib.Checkerr(client.StartStream(target_ip, rtp_port, amp_media_file)) tasks.AddNamed("stream", &golib.CleanupTask{Description: "stop rtp stream", Cleanup: func() { golib.Printerr(client.StopStream(target_ip, rtp_port)) golib.Printerr(client.Close()) }}) } if use_rtsp { if target_ip != rtp_ip { log.Printf("Warning: RTSP server will stream media to %v, but we are expecting it on %v\n", rtp_ip, target_ip) } log.Println("Starting stream using RTSP at", rtsp_url) rtspCommand, err := rtpClient.StartRtspClient(rtsp_url, rtp_port, "main.log") golib.Checkerr(err) tasks.AddNamed("rtsp", rtspCommand) } }
func parseFlags() { flag.IntVar(&num_clients, "num", num_clients, "Number of parallel RTP streams to initiate.\n"+ "\t\tproxy_port and rtp_port will be used as starting point for allocating the required number of ports.") flag.BoolVar(&close_stdin, "stdin", close_stdin, "Exit when stdin is closed") flag.BoolVar(&close_int, "int", close_int, "Exit when INT signal is received") flag.BoolVar(&show_dropped_packets_stats, "dropped_packet_stats", show_dropped_packets_stats, "Show numbers of packets dropped within the gortp stack") flag.BoolVar(&print_stats, "stats", print_stats, "Show various statistics about traffic") flag.BoolVar(&running_average, "average", running_average, "Show statistics averaged over the last 3 seconds") flag.BoolVar(&print_ctrl_events, "rtcp", print_ctrl_events, "Print RTCP events") flag.BoolVar(&use_rtsp, "rtsp", use_rtsp, "Initiate an RTSP session from the URL given by -rtsp_url") flag.StringVar(&rtsp_url, "rtsp_url", rtsp_url, "Set the URL used if -rtsp is given") flag.BoolVar(&use_amp, "amp", use_amp, "Initiate an AMP session at the server given by -amp_url") flag.StringVar(&_url, "amp_url", amp_url, "The AMP server used if -amp is given") flag.StringVar(&_media_file, "amp_file", amp_media_file, "The media file used with -amp") flag.BoolVar(&use_proxy, "proxy", use_proxy, "Route the RTP traffic through a proxy") flag.IntVar(&proxy_port, "proxy_port", proxy_port, "With -proxy, the port to receive traffic and forward it to -rtp_port") flag.BoolVar(&pretend_proxy, "pretend_proxy", pretend_proxy, "Don't really use proxies, but listen on the port that should receive the forwarded traffic. Implies -proxy.") flag.BoolVar(&use_pcp, "pcp", use_pcp, "Use external PCP server to satisfy -proxy. Implies -proxy") flag.StringVar(&pcp_url, "pcp_url", pcp_url, "The PCP server used for -pcp") flag.StringVar(&rtp_ip, "rtp", rtp_ip, "The local IP used to receive RTP/RTCP traffic") flag.IntVar(&start_rtp_port, "rtp_port", start_rtp_port, "The local port to receive RTP traffic") flag.BoolVar(&use_load, "load", use_load, "Listen for Load traffic instead of RTP/RTCP traffic") flag.BoolVar(&print_load_packets, "print_load_packets", print_load_packets, "Print incoming Load packets with timestamp") flag.Float64Var(&client_timeout, "timeout", client_timeout, "Timeout for client requests, if any are used") flag.Parse() use_proxy = use_proxy || use_pcp use_proxy = use_proxy || pretend_proxy if use_load && use_rtsp { golib.Checkerr(fmt.Errorf("-load cannot be used with -rtsp")) } }
func main() { loadBackend := flag.Bool("load", false, "Use Load servers to create the streams, instead of regular AMP Media servers") useHeartbeat := flag.Bool("heartbeat", false, "Use heartbeat-based fault detection instead of active ping-based detection") _heartbeat_frequency := flag.Uint("heartbeat_frequency", 200, "Time between two heartbeats which observers will send (milliseconds)") _heartbeat_timeout := flag.Uint("heartbeat_timeout", 350, "Time between two heartbeats before assuming offline server (milliseconds)") amp_addr := protocols.ParseServerFlags("0.0.0.0", 7779) heartbeat_frequency := time.Duration(*_heartbeat_frequency) * time.Millisecond heartbeat_timeout := time.Duration(*_heartbeat_timeout) * time.Millisecond var detector_factory balancer.FaultDetectorFactory tasks := golib.NewTaskGroup() var heartbeatServer *heartbeat.HeartbeatServer if *useHeartbeat { var err error heartbeatServer, err = heartbeat.NewHeartbeatServer(heartbeat_server) golib.Checkerr(err) go printServerErrors("Heartbeat", heartbeatServer.Server) log.Println("Listening for Heartbeats on", heartbeatServer.LocalAddr()) detector_factory = func(endpoint string) (protocols.FaultDetector, error) { return heartbeatServer.ObserveServer(endpoint, heartbeat_frequency, heartbeat_timeout) } tasks.AddNamed("heartbeat", heartbeatServer) } else { detector_factory = func(endpoint string) (protocols.FaultDetector, error) { detector, err := ping.DialNewFaultDetector(endpoint) if err != nil { return nil, err } detector.Start() return detector, nil } } protocol, err := protocols.NewProtocol("AMP", amp.Protocol, ping.Protocol, heartbeat.Protocol) golib.Checkerr(err) baseServer, err := protocols.NewServer(amp_addr, protocol) golib.Checkerr(err) server, err := amp_balancer.RegisterPluginServer(baseServer) golib.Checkerr(err) tasks.AddNamed("server", server) ampPlugin := amp_balancer.NewAmpBalancingPlugin(detector_factory) server.AddPlugin(ampPlugin) pcpPlugin := amp_balancer.NewPcpBalancingPlugin(detector_factory) server.AddPlugin(pcpPlugin) if *loadBackend { for _, load := range load_servers { err := ampPlugin.AddBackendServer(load, stateChangePrinter) golib.Checkerr(err) } } else { for _, amp := range amp_servers { err := ampPlugin.AddBackendServer(amp, stateChangePrinter) golib.Checkerr(err) } } for _, pcp := range pcp_servers { err := pcpPlugin.AddBackendServer(pcp, stateChangePrinter) golib.Checkerr(err) } go printServerErrors("Server", server.Server) server.SessionStartedCallback = printSessionStarted server.SessionStoppedCallback = printSessionStopped log.Println("Listening to AMP on " + amp_addr) log.Println("Press Ctrl-C to close") if heartbeatServer != nil { tasks.Add(heartbeatServer) } tasks.Add(&golib.NoopTask{golib.ExternalInterrupt(), "external interrupt"}) tasks.WaitAndExit() }
func makeProxyPCP(client *pcp.Client, listenPort, targetPort int) { golib.Checkerr(client.StartProxy(pcpProxyAddrs(listenPort, targetPort))) }
func pcpProxyIp() string { proxy_ip, _, err := net.SplitHostPort(pcp_url) golib.Checkerr(err) return proxy_ip }