function retrieveURLasync($ident, $urls, $logger, $ans_req = 1, $match = "^OK", $returl = False, $timeout = 10, $curlopts) { $mh = curl_multi_init(); $ch = array(); foreach ($urls as $url) { $handle = curl_init(); curl_settings($logger, $ident, $handle, $url, $timeout, $curlopts); curl_multi_add_handle($mh, $handle); $ch[$handle] = $handle; } $ans_arr = array(); do { while (curl_multi_exec($mh, $active) == CURLM_CALL_MULTI_PERFORM) { } while ($info = curl_multi_info_read($mh)) { $logger->log(LOG_DEBUG, "{$ident} curl multi info : ", $info); if ($info['result'] == CURLE_OK) { $str = curl_multi_getcontent($info['handle']); $logger->log(LOG_DEBUG, "{$ident} curl multi content : {$str}"); if (preg_match("/{$match}/", $str)) { $logger->log(LOG_DEBUG, "{$ident} response matches {$match}"); $error = curl_error($info['handle']); $errno = curl_errno($info['handle']); $cinfo = curl_getinfo($info['handle']); $logger->log(LOG_INFO, "{$ident} errno/error: {$errno}/{$error}", $cinfo); if ($returl) { $ans_arr[] = "url=" . $cinfo['url'] . "\n" . $str; } else { $ans_arr[] = $str; } } if (count($ans_arr) >= $ans_req) { foreach ($ch as $h) { curl_multi_remove_handle($mh, $h); curl_close($h); } curl_multi_close($mh); return $ans_arr; } curl_multi_remove_handle($mh, $info['handle']); curl_close($info['handle']); unset($ch[$info['handle']]); } curl_multi_select($mh); } } while ($active); foreach ($ch as $h) { curl_multi_remove_handle($mh, $h); curl_close($h); } curl_multi_close($mh); if (count($ans_arr) > 0) { return $ans_arr; } return false; }
public function reSync($older_than, $timeout) { $this->log(LOG_DEBUG, 'starting resync'); /* Loop over all unique servers in queue */ $queued_limit = time() - $older_than; $server_res = $this->db->customQuery("select distinct server from queue WHERE queued < " . $queued_limit . " or queued is null"); while ($my_server = $this->db->fetchArray($server_res)) { $this->log(LOG_DEBUG, "Processing queue for server " . $my_server['server']); $res = $this->db->customQuery("select * from queue WHERE (queued < " . $queued_limit . " or queued is null) and server='" . $my_server['server'] . "'"); $ch = curl_init(); while ($entry = $this->db->fetchArray($res)) { $this->log(LOG_INFO, "server=" . $entry['server'] . ", server_nonce=" . $entry['server_nonce'] . ", info=" . $entry['info']); $url = $entry['server'] . "?otp=" . $entry['otp'] . "&modified=" . $entry['modified'] . "&" . $this->otpPartFromInfoString($entry['info']); /* Send out sync request */ curl_settings($this, 'YK-VAL resync', $ch, $url, $timeout, $this->curlopts); $response = curl_exec($ch); if ($response == False) { $this->log(LOG_NOTICE, 'Timeout. Stopping queue resync for server ' . $entry['server']); break; } if (preg_match('/status=OK/', $response)) { $resParams = $this->parseParamsFromMultiLineString($response); $this->log(LOG_DEBUG, 'response contains ', $resParams); /* Update database counters */ $this->updateDbCounters($resParams); /* Retrieve info from entry info string */ /* This is the counter values we had in our database *before* processing the current OTP. */ $validationParams = $this->localParamsFromInfoString($entry['info']); /* This is the data from the current OTP. */ $otpParams = $this->otpParamsFromInfoString($entry['info']); /* Fetch current information from our database */ $localParams = $this->getLocalParams($otpParams['yk_publicname']); $this->log(LOG_DEBUG, 'validation params: ', $validationParams); $this->log(LOG_DEBUG, 'OTP params: ', $otpParams); /* Check for warnings */ if ($this->countersHigherThan($validationParams, $resParams)) { $this->log(LOG_NOTICE, 'Remote server out of sync compared to counters at validation request time. '); } if ($this->countersHigherThan($resParams, $validationParams)) { if ($this->countersEqual($resParams, $otpParams)) { $this->log(LOG_INFO, 'Remote server had received the current counter values already. '); } else { $this->log(LOG_NOTICE, 'Local server out of sync compared to counters at validation request time. '); } } if ($this->countersHigherThan($localParams, $resParams)) { $this->log(LOG_WARNING, 'Remote server out of sync compared to current local counters. '); } if ($this->countersHigherThan($resParams, $localParams)) { $this->log(LOG_WARNING, 'Local server out of sync compared to current local counters. Local server updated. '); } if ($this->countersHigherThan($resParams, $otpParams)) { $this->log(LOG_ERR, 'Remote server has higher counters than OTP. This response would have marked the OTP as invalid. '); } elseif ($this->countersEqual($resParams, $otpParams) && $resParams['nonce'] != $otpParams['nonce']) { $this->log(LOG_ERR, 'Remote server has equal counters as OTP and nonce differs. This response would have marked the OTP as invalid.'); } /* Deletion */ $this->log(LOG_DEBUG, 'deleting queue entry with modified=' . $entry['modified'] . ' server_nonce=' . $entry['server_nonce'] . ' server=' . $entry['server']); $this->db->deleteByMultiple('queue', array('modified' => $entry['modified'], 'server_nonce' => $entry['server_nonce'], 'server' => $entry['server'])); } else { if (preg_match('/status=BAD_OTP/', $response)) { $this->log(LOG_WARNING, 'Remote server says BAD_OTP, pointless to try again, removing from queue.'); $this->db->deleteByMultiple('queue', array('modified' => $entry['modified'], 'server_nonce' => $entry['server_nonce'], 'server' => $entry['server'])); } else { $this->log(LOG_ERR, 'Remote server refused our sync request. Check remote server logs.'); } } } /* End of loop over each queue entry for a server */ curl_close($ch); $this->db->closeCursor($res); } /* End of loop over each distinct server in queue */ $this->db->closeCursor($server_res); return true; }