package webconnectivity // // TCP/IP analysis // import ( "fmt" "net" "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) // analysisTCPIPToplevel is the toplevel analysis function for TCP/IP results. // // This algorithm has two objectives: // // 1. walk the list of TCP connect attempts and mark each of them as // Status.Blocked = true | false | null depending on what the TH observed // for the same set of IP addresses (it's ugly to modify a data struct // in place, but this algorithm is defined by the spec); // // 2. assign the analysisFlagTCPIPBlocking flag to XBlockingFlags if // we see any TCP endpoint for which Status.Blocked is true. func (tk *TestKeys) analysisTCPIPToplevel(logger model.Logger) { // if we don't have a control result, do nothing. if tk.Control == nil || len(tk.Control.TCPConnect) <= 0 { return } var ( istrue = true isfalse = false ) // walk the list of probe results and compare with TH results for _, entry := range tk.TCPConnect { // skip successful entries failure := entry.Status.Failure if failure == nil { entry.Status.Blocked = &isfalse continue // did not fail } // make sure we exclude the IPv6 failures caused by lack of // proper IPv6 support by the probe ipv6, err := netxlite.IsIPv6(entry.IP) if err != nil { continue // looks like a bug } if ipv6 { ignore := (*failure == netxlite.FailureNetworkUnreachable || *failure == netxlite.FailureHostUnreachable) if ignore { // this occurs when we don't have IPv6 on the probe continue } } // obtain the corresponding endpoint epnt := net.JoinHostPort(entry.IP, fmt.Sprintf("%d", entry.Port)) ctrl, found := tk.Control.TCPConnect[epnt] if !found { continue // only the probe tested this, so hard to say anything... } if ctrl.Failure != nil { // If the TH failed as well, don't set XBlockingFlags and // also don't bother with setting .Status.Blocked thus leaving // it null. Performing precise error mapping should be a job // for the pipeline rather than for the probe. continue } logger.Warnf( "TCP/IP: unexpected failure %s for %s (see #%d)", *failure, epnt, entry.TransactionID, ) entry.Status.Blocked = &istrue tk.BlockingFlags |= analysisFlagTCPIPBlocking } }