createConn will connect to the server and wrap the appropriate bufio structures. It will do the right thing when an existing connection is in place.
()
| 2303 | // bufio structures. It will do the right thing when an existing |
| 2304 | // connection is in place. |
| 2305 | func (nc *Conn) createConn() (err error) { |
| 2306 | if nc.Opts.Timeout < 0 { |
| 2307 | return ErrBadTimeout |
| 2308 | } |
| 2309 | if _, cur := nc.currentServer(); cur == nil { |
| 2310 | return ErrNoServers |
| 2311 | } |
| 2312 | |
| 2313 | // If we have a reference to an in-process server then establish a |
| 2314 | // connection using that. |
| 2315 | if nc.Opts.InProcessServer != nil { |
| 2316 | conn, err := nc.Opts.InProcessServer.InProcessConn() |
| 2317 | if err != nil { |
| 2318 | return fmt.Errorf("failed to get in-process connection: %w", err) |
| 2319 | } |
| 2320 | nc.conn = conn |
| 2321 | nc.bindToNewConn() |
| 2322 | return nil |
| 2323 | } |
| 2324 | |
| 2325 | // We will auto-expand host names if they resolve to multiple IPs |
| 2326 | hosts := []string{} |
| 2327 | u := nc.current.URL |
| 2328 | |
| 2329 | if !nc.Opts.SkipHostLookup && net.ParseIP(u.Hostname()) == nil { |
| 2330 | addrs, _ := net.LookupHost(u.Hostname()) |
| 2331 | for _, addr := range addrs { |
| 2332 | hosts = append(hosts, net.JoinHostPort(addr, u.Port())) |
| 2333 | } |
| 2334 | } |
| 2335 | // Fall back to what we were given. |
| 2336 | if len(hosts) == 0 { |
| 2337 | hosts = append(hosts, u.Host) |
| 2338 | } |
| 2339 | |
| 2340 | // CustomDialer takes precedence. If not set, use Opts.Dialer which |
| 2341 | // is set to a default *net.Dialer (in Connect()) if not explicitly |
| 2342 | // set by the user. |
| 2343 | dialer := nc.Opts.CustomDialer |
| 2344 | if dialer == nil { |
| 2345 | // We will copy and shorten the timeout if we have multiple hosts to try. |
| 2346 | copyDialer := *nc.Opts.Dialer |
| 2347 | copyDialer.Timeout = copyDialer.Timeout / time.Duration(len(hosts)) |
| 2348 | dialer = ©Dialer |
| 2349 | } |
| 2350 | |
| 2351 | if len(hosts) > 1 && !nc.Opts.NoRandomize { |
| 2352 | rand.Shuffle(len(hosts), func(i, j int) { |
| 2353 | hosts[i], hosts[j] = hosts[j], hosts[i] |
| 2354 | }) |
| 2355 | } |
| 2356 | for _, host := range hosts { |
| 2357 | nc.conn, err = dialer.Dial("tcp", host) |
| 2358 | if err == nil { |
| 2359 | break |
| 2360 | } |
| 2361 | } |
| 2362 | if err != nil { |
no test coverage detected