| 1294 | } |
| 1295 | |
| 1296 | static int connect_to_daemon(int *sdptr, request_rec *r, |
| 1297 | cgid_server_conf *conf) |
| 1298 | { |
| 1299 | int sd; |
| 1300 | int connect_tries; |
| 1301 | int connect_errno; |
| 1302 | apr_interval_time_t sliding_timer; |
| 1303 | |
| 1304 | connect_tries = 0; |
| 1305 | sliding_timer = 100000; /* 100 milliseconds */ |
| 1306 | while (1) { |
| 1307 | connect_errno = 0; |
| 1308 | ++connect_tries; |
| 1309 | if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { |
| 1310 | return log_scripterror(r, conf, HTTP_INTERNAL_SERVER_ERROR, errno, |
| 1311 | APLOGNO(01255), "unable to create socket to cgi daemon"); |
| 1312 | } |
| 1313 | if (connect(sd, (struct sockaddr *)server_addr, server_addr_len) < 0) { |
| 1314 | /* Save errno for later */ |
| 1315 | connect_errno = errno; |
| 1316 | /* ECONNREFUSED means the listen queue is full; ENOENT means that |
| 1317 | * the cgid server either hasn't started up yet, or we're pointing |
| 1318 | * at the wrong socket file */ |
| 1319 | if ((errno == ECONNREFUSED || errno == ENOENT) && |
| 1320 | connect_tries < DEFAULT_CONNECT_ATTEMPTS) { |
| 1321 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, errno, r, APLOGNO(01256) |
| 1322 | "connect #%d to cgi daemon failed, sleeping before retry", |
| 1323 | connect_tries); |
| 1324 | close(sd); |
| 1325 | apr_sleep(sliding_timer); |
| 1326 | if (sliding_timer < apr_time_from_sec(2)) { |
| 1327 | sliding_timer *= 2; |
| 1328 | } |
| 1329 | } |
| 1330 | else { |
| 1331 | close(sd); |
| 1332 | return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, errno, APLOGNO(01257), |
| 1333 | "unable to connect to cgi daemon after multiple tries"); |
| 1334 | } |
| 1335 | } |
| 1336 | else { |
| 1337 | apr_pool_cleanup_register(r->pool, (void *)((long)sd), |
| 1338 | close_unix_socket, apr_pool_cleanup_null); |
| 1339 | break; /* we got connected! */ |
| 1340 | } |
| 1341 | |
| 1342 | /* If we didn't find the socket but the server was not recently restarted, |
| 1343 | * chances are there's something wrong with the cgid daemon |
| 1344 | */ |
| 1345 | if (connect_errno == ENOENT && |
| 1346 | apr_time_sec(apr_time_now() - ap_scoreboard_image->global->restart_time) > |
| 1347 | DEFAULT_CONNECT_STARTUP_DELAY) { |
| 1348 | return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno, |
| 1349 | APLOGNO(02833), |
| 1350 | apr_pstrcat(r->pool, |
| 1351 | "ScriptSock ", sockname, " does not exist", NULL)); |
| 1352 | } |
| 1353 |
no test coverage detected