void Connection::handle_connect(const boost::system::error_code & err) { if (!err) { handle_connect_success(); }else { handle_connect_error(); } }
static void handle_connect(struct argos_net_conn *conn) { assert(conn->state == ARGOS_NET_CONN_CONNECTING); /* * connect() completed, but did it succeed or fail? getpeername() will * tell us. reference: http://cr.yp.to/docs/connect.html */ struct sockaddr_in sin; socklen_t slen = sizeof(sin); if (getpeername(conn->sock, (struct sockaddr*)&sin, &slen) == -1) { if (errno == ENOTCONN) { /* connect failed; ok now use error slippage to get the real error */ char c; int rv = read(conn->sock, &c, 1); assert(rv == -1); handle_connect_failure(conn); } else if (errno == ECONNRESET) { /* * not sure if this can actually happen - perhaps with perfect * timing (connection lost right before we call getpeername) */ orion_log_warn_errno("getpeername"); reset_connection(conn, 0); } else { /* this is unexpected... */ orion_log_crit_errno("getpeername"); kill_connection(conn); orion_log_crit("unexpected getpeername() error after asynchronous" " connect() selected for writability; connection is now dead"); } } else { /* connect succeeded */ orion_log_info("connect() succeeded asynchronously"); handle_connect_success(conn); } }
static int attempt_connect(struct argos_net_conn *conn) { if (!conn->connect_failed) orion_log_func(); assert(conn->state == ARGOS_NET_CONN_IDLE); /* create and set up the actual socket */ conn->sock = socket(AF_INET, SOCK_STREAM, 0); if (conn->sock < 0) { orion_log_errno("socket"); goto fail; } /* set non-blocking on socket */ int status = fcntl(conn->sock, F_GETFL, NULL); if (status < 0) { orion_log_crit_errno("fcntl(F_GETFL)"); goto fail; } status |= O_NONBLOCK; if (fcntl(conn->sock, F_SETFL, status) < 0) { orion_log_crit_errno("fcntl(F_SETFL)"); goto fail; } /* prevent socket from throwing SIGPIPE signals */ int on = 1; if (setsockopt(conn->sock, SOL_SOCKET, SO_NOSIGPIPE, (void *)&on, sizeof(on)) < 0) { orion_log_crit_errno("setsockopt(SO_NOSIGPIPE)"); goto fail; } /* select for writes (that's how completion of a connect() is signaled) */ int rv = async_add_write_fd(conn->sock, ARGOS_NET_CONNECT_ASYNCPRIO, writable_cb, write_cb, conn); if (rv != 0) { orion_log_errno("async_add_write_fd"); async_remove_fd(conn->sock); goto fail; } /* finally ready to attempt the connect() call */ rv = connect(conn->sock, (struct sockaddr*)&conn->remote_addr, sizeof(conn->remote_addr)); if (rv == -1) return handle_connect_failure(conn); /* else, rv=0 which means instant success (odd...) */ orion_log_info("connect() succeeded immediately"); handle_connect_success(conn); return 0; fail: /* * something very bad happened; presumably either there is a code bug or the * OS is in bad shape (e.g. out of memory, no more file descriptors, etc.) */ kill_connection(conn); orion_log_crit("failed to create network client"); return -1; }