1 2 /* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7 #include <nxt_main.h> 8 9 10 void 11 nxt_conn_sys_socket(nxt_task_t *task, void *obj, void *data) 12 { 13 nxt_conn_t *c; 14 nxt_work_handler_t handler; 15 16 c = obj; 17 18 if (nxt_conn_socket(task, c) == NXT_OK) { 19 c->socket.write_work_queue = c->write_work_queue; 20 handler = c->io->connect; 21 22 } else { 23 handler = c->write_state->error_handler; 24 } 25 26 nxt_work_queue_add(&task->thread->engine->connect_work_queue, 27 handler, task, c, data); 28 } 29 30 31 void 32 nxt_conn_io_connect(nxt_task_t *task, void *obj, void *data) 33 { 34 nxt_conn_t *c; 35 nxt_work_handler_t handler; 36 nxt_event_engine_t *engine; 37 const nxt_conn_state_t *state; 38 39 c = obj; 40 41 state = c->write_state; 42 43 switch (nxt_socket_connect(task, c->socket.fd, c->remote)) { 44 45 case NXT_OK: 46 c->socket.write_ready = 1; 47 handler = state->ready_handler; 48 break; 49 50 case NXT_AGAIN: 51 c->socket.write_handler = nxt_conn_connect_test; 52 c->socket.error_handler = state->error_handler; 53 54 engine = task->thread->engine; 55 56 nxt_conn_timer(engine, c, state, &c->write_timer); 57 58 nxt_fd_event_enable_write(engine, &c->socket); 59 return; 60 61 case NXT_DECLINED: 62 handler = state->close_handler; 63 break; 64 65 default: /* NXT_ERROR */ 66 handler = state->error_handler; 67 break; 68 } 69 70 nxt_work_queue_add(c->write_work_queue, handler, task, c, data); 71 } 72 73 74 nxt_int_t 75 nxt_conn_socket(nxt_task_t *task, nxt_conn_t *c) 76 { 77 nxt_uint_t family; 78 nxt_socket_t s; 79 80 nxt_debug(task, "event conn socket"); 81 82 family = c->remote->u.sockaddr.sa_family; 83 84 s = nxt_socket_create(task, family, c->remote->type, 0, NXT_NONBLOCK); 85 86 if (nxt_slow_path(s == -1)) { 87 return NXT_ERROR; 88 } 89 90 c->sendfile = 1; 91 92 #if (NXT_HAVE_UNIX_DOMAIN && NXT_SOLARIS) 93 94 if (family == AF_UNIX) { 95 /* Solaris AF_UNIX does not support sendfilev(). */ 96 c->sendfile = 0; 97 } 98 99 #endif 100 101 c->socket.fd = s; 102 103 c->socket.task = task; 104 c->read_timer.task = task; 105 c->write_timer.task = task; 106 107 if (c->local != NULL) { 108 if (nxt_slow_path(nxt_socket_bind(task, s, c->local, 0) != NXT_OK)) { 109 nxt_socket_close(task, s); 110 return NXT_ERROR; 111 } 112 } 113 114 return NXT_OK; 115 } 116 117 118 void 119 nxt_conn_connect_test(nxt_task_t *task, void *obj, void *data) 120 { 121 int ret, err; 122 socklen_t len; 123 nxt_conn_t *c; 124 125 c = obj; 126 127 nxt_debug(task, "event connect test fd:%d", c->socket.fd); 128 129 nxt_fd_event_block_write(task->thread->engine, &c->socket); 130 131 if (c->write_state->timer_autoreset) { 132 nxt_timer_disable(task->thread->engine, &c->write_timer); 133 } 134 135 err = 0; 136 len = sizeof(int); 137 138 /* 139 * Linux and BSDs return 0 and store a pending error in the err argument; 140 * Solaris returns -1 and sets the errno. 141 */ 142 143 ret = getsockopt(c->socket.fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len); 144 145 if (nxt_slow_path(ret == -1)) { 146 err = nxt_errno; 147 } 148 149 if (err == 0) { 150 nxt_work_queue_add(c->write_work_queue, c->write_state->ready_handler, 151 task, c, data); 152 return; 153 } 154 155 c->socket.error = err; 156 157 nxt_log(task, nxt_socket_error_level(err), "connect(%d, %*s) failed %E", 158 c->socket.fd, (size_t) c->remote->length, 159 nxt_sockaddr_start(c->remote)); 160 161 nxt_conn_connect_error(task, c, data); 162 } 163 164 165 void 166 nxt_conn_connect_error(nxt_task_t *task, void *obj, void *data) 167 { 168 nxt_conn_t *c; 169 nxt_work_handler_t handler; 170 const nxt_conn_state_t *state; 171 172 c = obj; 173 174 state = c->write_state; 175 176 switch (c->socket.error) { 177 178 case NXT_ECONNREFUSED: 179 #if (NXT_LINUX) 180 case NXT_EAGAIN: 181 /* 182 * Linux returns EAGAIN instead of ECONNREFUSED 183 * for UNIX sockets if a listen queue is full. 184 */ 185 #endif 186 handler = state->close_handler; 187 break; 188 189 default: 190 handler = state->error_handler; 191 break; 192 } 193 194 nxt_work_queue_add(c->write_work_queue, handler, task, c, data); 195 } 196