| 204 | } |
| 205 | |
| 206 | int |
| 207 | Connection::connect(sockaddr const *target, NetVCOptions const &opt) |
| 208 | { |
| 209 | ink_assert(sock.is_ok()); |
| 210 | ink_assert(is_bound); |
| 211 | ink_assert(!is_connected); |
| 212 | |
| 213 | int res; |
| 214 | |
| 215 | if (target != nullptr) { |
| 216 | this->setRemote(target); |
| 217 | } |
| 218 | |
| 219 | // apply dynamic options with this.addr initialized |
| 220 | apply_options(opt); |
| 221 | |
| 222 | cleaner<Connection> cleanup(this, &Connection::_cleanup); // mark for close until we succeed. |
| 223 | |
| 224 | if (opt.f_tcp_fastopen && !opt.f_blocking_connect) { |
| 225 | // TCP Fast Open is (effectively) a non-blocking connect, so set the |
| 226 | // return value we would see in that case. |
| 227 | errno = EINPROGRESS; |
| 228 | res = -1; |
| 229 | } else { |
| 230 | res = sock.connect(&this->addr.sa, ats_ip_size(&this->addr.sa)); |
| 231 | } |
| 232 | |
| 233 | // It's only really an error if either the connect was blocking |
| 234 | // or it wasn't blocking and the error was other than EINPROGRESS. |
| 235 | // (Is EWOULDBLOCK ok? Does that start the connect?) |
| 236 | // We also want to handle the cases where the connect blocking |
| 237 | // and IO blocking differ, by turning it on or off as needed. |
| 238 | if (-1 == res && (opt.f_blocking_connect || !(EINPROGRESS == errno || EWOULDBLOCK == errno))) { |
| 239 | return -errno; |
| 240 | } else if (opt.f_blocking_connect && !opt.f_blocking) { |
| 241 | if (-1 == sock.set_nonblocking()) { |
| 242 | return -errno; |
| 243 | } |
| 244 | } else if (!opt.f_blocking_connect && opt.f_blocking) { |
| 245 | if (-1 == safe_blocking(sock.get_fd())) { |
| 246 | return -errno; |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | cleanup.reset(); |
| 251 | |
| 252 | // Only mark this connection as connected if we successfully called connect(2). When we |
| 253 | // do the TCP Fast Open later, we need to track this accurately. |
| 254 | is_connected = !(opt.f_tcp_fastopen && !opt.f_blocking_connect); |
| 255 | return 0; |
| 256 | } |
| 257 | |
| 258 | void |
| 259 | Connection::_cleanup() |
no test coverage detected