connectOne makes one connection attempt to a single host.
(ctx context.Context, config *Config, connectConfig *connectOneConfig, ignoreNotPreferredErr bool, )
| 311 | |
| 312 | // connectOne makes one connection attempt to a single host. |
| 313 | func connectOne(ctx context.Context, config *Config, connectConfig *connectOneConfig, |
| 314 | ignoreNotPreferredErr bool, |
| 315 | ) (*PgConn, error) { |
| 316 | pgConn := new(PgConn) |
| 317 | pgConn.config = config |
| 318 | pgConn.cleanupDone = make(chan struct{}) |
| 319 | pgConn.customData = make(map[string]any) |
| 320 | |
| 321 | var err error |
| 322 | |
| 323 | newPerDialConnectError := func(msg string, err error) *perDialConnectError { |
| 324 | err = normalizeTimeoutError(ctx, err) |
| 325 | e := &perDialConnectError{address: connectConfig.address, originalHostname: connectConfig.originalHostname, err: fmt.Errorf("%s: %w", msg, err)} |
| 326 | return e |
| 327 | } |
| 328 | |
| 329 | maxProtocolVersion, err := parseProtocolVersion(config.MaxProtocolVersion) |
| 330 | if err != nil { |
| 331 | return nil, newPerDialConnectError("invalid max_protocol_version", err) |
| 332 | } |
| 333 | minProtocolVersion, err := parseProtocolVersion(config.MinProtocolVersion) |
| 334 | if err != nil { |
| 335 | return nil, newPerDialConnectError("invalid min_protocol_version", err) |
| 336 | } |
| 337 | |
| 338 | pgConn.conn, err = config.DialFunc(ctx, connectConfig.network, connectConfig.address) |
| 339 | if err != nil { |
| 340 | return nil, newPerDialConnectError("dial error", err) |
| 341 | } |
| 342 | |
| 343 | if connectConfig.tlsConfig != nil { |
| 344 | pgConn.contextWatcher = ctxwatch.NewContextWatcher(&DeadlineContextWatcherHandler{Conn: pgConn.conn}) |
| 345 | pgConn.contextWatcher.Watch(ctx) |
| 346 | var ( |
| 347 | tlsConn net.Conn |
| 348 | err error |
| 349 | ) |
| 350 | if config.SSLNegotiation == "direct" { |
| 351 | tlsConn = tls.Client(pgConn.conn, connectConfig.tlsConfig) |
| 352 | } else { |
| 353 | tlsConn, err = startTLS(pgConn.conn, connectConfig.tlsConfig) |
| 354 | } |
| 355 | pgConn.contextWatcher.Unwatch() // Always unwatch `netConn` after TLS. |
| 356 | if err != nil { |
| 357 | pgConn.conn.Close() |
| 358 | return nil, newPerDialConnectError("tls error", err) |
| 359 | } |
| 360 | |
| 361 | pgConn.conn = tlsConn |
| 362 | pgConn.tlsConfig = connectConfig.tlsConfig |
| 363 | } |
| 364 | |
| 365 | if config.AfterNetConnect != nil { |
| 366 | pgConn.conn, err = config.AfterNetConnect(ctx, config, pgConn.conn) |
| 367 | if err != nil { |
| 368 | pgConn.conn.Close() |
| 369 | return nil, newPerDialConnectError("AfterNetConnect failed", err) |
| 370 | } |
no test coverage detected