{"record":{"id":"183e92c9a9538cf7","repo":"txthinking/brook","slug":"invalid-dial-with-ip","errorCode":null,"errorMessage":"Invalid dial with IP","messagePattern":"Invalid dial with IP","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/dialwithip/dialwithip.go","lineNumber":32,"sourceCode":"\npackage dialwithip\n\nimport (\n\t\"errors\"\n\t\"net\"\n\n\t\"github.com/txthinking/brook\"\n\t\"github.com/txthinking/socks5\"\n)\n\ntype DialWithIP struct {\n\tIP4 net.IP\n\tIP6 net.IP\n}\n\nfunc NewDialWithIP(ip4, ip6 string) (*DialWithIP, error) {\n\tif ip4 != \"\" && (net.ParseIP(ip4) == nil || net.ParseIP(ip4).To4() == nil) {\n\t\treturn nil, errors.New(\"Invalid dial with IP\")\n\t}\n\tif ip6 != \"\" && (net.ParseIP(ip6) == nil || net.ParseIP(ip6).To4() != nil) {\n\t\treturn nil, errors.New(\"Invalid dial with IP\")\n\t}\n\td := &DialWithIP{}\n\tif ip4 != \"\" {\n\t\td.IP4 = net.ParseIP(ip4).To4()\n\t}\n\tif ip6 != \"\" {\n\t\td.IP6 = net.ParseIP(ip6).To16()\n\t}\n\treturn d, nil\n}\n\nfunc (p *DialWithIP) TouchBrook() {\n\tbrook.DialTCP = func(network string, laddr, raddr string) (net.Conn, error) {\n\t\tvar la, ra *net.TCPAddr\n\t\tif laddr != \"\" {","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/txthinking/brook/blob/5cd13ef3b1fb574e88ebf2c1b5d95f2ebe1342c8/plugins/dialwithip/dialwithip.go#L14-L50","documentation":"NewDialWithIP builds a DialWithIP plugin from an IPv4 and an IPv6 address string. Before error [70] is thrown, the function validates the ip4 argument: it must either be empty or parse as a valid IP via net.ParseIP AND convert to a 4-byte IPv4 address via To4(). This error means the supplied ip4 string was non-empty but was not a valid IPv4 address (it was unparseable, or it was an IPv6/different form), so the constructor aborts rather than storing a bogus address.","triggerScenarios":"Calling NewDialWithIP with a non-empty ip4 string that fails net.ParseIP (e.g. \"999.1.1.1\", \"192.168.1\", \"example.com\") or that parses but is not IPv4 (e.g. \"::1\", \"2001:db8::1\", an IPv4-in-IPv6 form where To4() returns nil).","commonSituations":"Passing a hostname instead of an IP in config; swapping the arguments and passing an IPv6 address as ip4; typos or extra whitespace/port suffixes like \"10.0.0.1:53\" in the IPv4 field; environment-specific config files where an IPv6 address was pasted into the IPv4 slot.","solutions":["Check the ip4 argument and correct it to a valid IPv4 address (e.g. \"10.0.0.1\"); if you only have IPv6, pass \"\" as ip4 and supply the address as ip6 instead.","Pre-validate with net.ParseIP(ip4).To4() != nil before calling NewDialWithIP to fail fast with a clearer message.","If the value is a hostname, resolve it first with net.LookupHost and pick the A record for ip4.","Trim whitespace and strip any port suffix from the string before passing it in."],"exampleFix":"// before\n_, err := brookplugin.NewDialWithIP(\"example.com\", \"2001:db8::1\")\n// after\nip4, _ := net.LookupHost(\"example.com\")\nd, err := brookplugin.NewDialWithIP(ip4[0], \"2001:db8::1\") // ip4[0] e.g. \"93.184.216.34\"","handlingStrategy":"validation","validationCode":"func isValidIPv4(s string) bool {\n    ip := net.ParseIP(strings.TrimSpace(s))\n    return s == \"\" || (ip != nil && ip.To4() != nil)\n}\n// call: if !isValidIPv4(ip4) { return fmt.Errorf(\"bad ipv4: %q\", ip4) }","typeGuard":"func isIPv4(s string) bool {\n    ip := net.ParseIP(s)\n    return ip != nil && ip.To4() != nil\n}","tryCatchPattern":"d, err := brookplugin.NewDialWithIP(ip4, ip6)\nif err != nil {\n    if err.Error() == \"Invalid dial with IP\" {\n        log.Fatalf(\"invalid IPv4 literal %q: must parse via net.ParseIP and To4()\", ip4)\n    }\n    return err\n}","preventionTips":["Always validate IP strings with net.ParseIP + To4()/To16() before passing to constructors.","Resolve hostnames to literal IPs before use; never pass DNS names where IPs are expected.","Trim whitespace and strip port/bracket suffixes from user-supplied addresses.","Keep ip4 and ip6 config fields clearly labeled to avoid argument-order swaps."],"tags":["go","network","ipv4","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"5cd13ef3b1fb574e88ebf2c1b5d95f2ebe1342c8","analyzedAt":"2026-09-06T04:35:00.432Z","contentChangedAt":"2026-09-06T04:35:00.432Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}