📄 ping.c
字号:
/****************************************************************************** libprozilla - a download accelerator library Copyright (C) 2001 Kalum Somaratna This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA******************************************************************************/#include "common.h"#include "prozilla.h"#include "connect.h"#include "misc.h"#include "url.h"#include "netrc.h"#include "debug.h"#include "ping.h"#define TCP_PING_PACKSIZE 3uerr_t tcp_ping(ping_t * ping_data){ unsigned int portnum; int status, noblock, flags; struct sockaddr_in server; struct hostent *hp, hostbuf; extern int h_errno; /* int opt; */ char *tmphstbuf; size_t hstbuflen = 2048; struct timeval start_time; struct timeval end_time; char ping_buf[TCP_PING_PACKSIZE]; int bytes_read; int standard_ping_milli_secs; assert(ping_data->host); tmphstbuf = kmalloc(hstbuflen); portnum = ping_data->port; memset((void *) &server, 0, sizeof(server)); hp = k_gethostname(ping_data->host, &hostbuf, &tmphstbuf, &hstbuflen); if (hp == NULL) return ping_data->err = HOSTERR; memcpy((void *) &server.sin_addr, hp->h_addr, hp->h_length); server.sin_family = hp->h_addrtype; server.sin_port = htons(portnum); /* Create a socket. */ if ((ping_data->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 1) { kfree(tmphstbuf); return ping_data->err = CONSOCKERR; } /* Experimental. */ flags = fcntl(ping_data->sock, F_GETFL, 0); if (flags != -1) noblock = fcntl(ping_data->sock, F_SETFL, flags | O_NONBLOCK); else noblock = -1; /* get start time */ gettimeofday(&start_time, 0); status = connect(ping_data->sock, (struct sockaddr *) &server, sizeof(server)); if ((status == -1) && (noblock != -1) && (errno == EINPROGRESS)) { fd_set writefd; FD_ZERO(&writefd); FD_SET(ping_data->sock, &writefd); status = select((ping_data->sock + 1), NULL, &writefd, NULL, &ping_data->timeout); /* Do we need to retry if the err is EINTR? */ if (status > 0) { socklen_t arglen = sizeof(int); if (getsockopt (ping_data->sock, SOL_SOCKET, SO_ERROR, &status, &arglen) < 0) status = errno; if (status != 0) errno = status, status = -1; if (errno == EINPROGRESS) errno = ETIMEDOUT; } else if (status == 0) errno = ETIMEDOUT, status = -1; } if (status < 0) { close_sock(&ping_data->sock); if (errno == ECONNREFUSED) { kfree(tmphstbuf); return ping_data->err = CONREFUSED; } else if (errno == ETIMEDOUT) { kfree(tmphstbuf); return ping_data->err = PINGTIMEOUT; } else { kfree(tmphstbuf); return ping_data->err = CONERROR; } } else { flags = fcntl(ping_data->sock, F_GETFL, 0); if (flags != -1) fcntl(ping_data->sock, F_SETFL, flags & ~O_NONBLOCK); } /* setsockopt(*sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&opt, (int) sizeof(opt)); */ kfree(tmphstbuf); /*So far so good connection established */ bytes_read = krecv(ping_data->sock, ping_buf, TCP_PING_PACKSIZE, 0, &ping_data->timeout); close_sock(&ping_data->sock); proz_debug("bytes read = %d", bytes_read); if (bytes_read == -1) { if (errno == ETIMEDOUT) return ping_data->err = PINGTIMEOUT; else return ping_data->err = READERR; } if (bytes_read == 0 || bytes_read < TCP_PING_PACKSIZE) return ping_data->err = READERR; /* the end time */ gettimeofday(&end_time, 0); proz_timeval_subtract(&ping_data->ping_time, &end_time, &start_time); /* standard_ping_milli_secs =(int)((((float)ping_data->ping_time.tv_usec/1000)+(((float)ping_data->ping_time.tv_sec)*1000))*3/(float)bytes_read); ping_data->ping_time.tv_sec=standard_ping_milli_secs/1000; ping_data->ping_time.tv_usec=standard_ping_milli_secs%1000; */ return ping_data->err = PINGOK;}void proz_mass_ping(ftps_request_t * request){ request->mass_ping_running = TRUE; if (pthread_create(&request->mass_ping_thread, NULL, (void *) &mass_ping, (void *) request) != 0) proz_die(_("Error: Not enough system resources"));}void proz_cancel_mass_ping(ftps_request_t * request){ /*TODO Rewrite so that this will terminate the pingin threads as well */ request->mass_ping_running = FALSE; pthread_cancel(request->mass_ping_thread); pthread_join(request->mass_ping_thread,0);}void mass_ping(ftps_request_t * request){ int i, j, k = 0, num_iter, num_left, simul_pings; pthread_t *ping_threads; ping_t *ping_requests; simul_pings = request->max_simul_pings; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); ping_threads = (pthread_t *) kmalloc(sizeof(pthread_t) * simul_pings); ping_requests = kmalloc(sizeof(ping_t) * request->num_mirrors); num_iter = request->num_mirrors / simul_pings; num_left = request->num_mirrors % simul_pings; proz_debug("Max simul pings=%d", simul_pings); proz_debug("request->num_mirrors=%d", request->num_mirrors); pthread_mutex_lock(&request->access_mutex); request->mass_ping_running = TRUE; pthread_mutex_unlock(&request->access_mutex); k = 0; for (i = 0; i < num_iter; i++) { for (j = 0; j < simul_pings; j++) { ping_t ping_request; memset(ping_requests + k, 0, sizeof(ping_request)); /*FIXME */ ping_requests[k].timeout.tv_sec = request->ping_timeout.tv_sec; ping_requests[k].timeout.tv_usec = request->ping_timeout.tv_usec; ping_requests[k].host = strdup(request->mirrors[k].server_name); ping_requests[k].port = 21; if (pthread_create(&ping_threads[j], NULL, (void *) &tcp_ping, (void *) (ping_requests + k)) != 0) proz_die("Error: Not enough system resources" "to create thread!\n"); k++; } k -= simul_pings; for (j = 0; j < simul_pings; j++) { /*Wait till the end of each thread. */ pthread_join(ping_threads[j], NULL); if (ping_requests[k].err == PINGOK) { pthread_mutex_lock(&request->access_mutex); request->mirrors[k].milli_secs = (ping_requests[k].ping_time.tv_sec * 1000) + (ping_requests[k].ping_time.tv_usec / 1000); request->mirrors[k].status = RESPONSEOK; pthread_mutex_unlock(&request->access_mutex); } else { pthread_mutex_lock(&request->access_mutex); request->mirrors[k].status = NORESPONSE; pthread_mutex_unlock(&request->access_mutex); } k++; } } for (j = 0; j < num_left; j++) { ping_t ping_request; memset(ping_requests + k, 0, sizeof(ping_request)); /*FIXME */ ping_requests[k].timeout.tv_sec = request->ping_timeout.tv_sec; ping_requests[k].timeout.tv_usec = 0; ping_requests[k].host = strdup(request->mirrors[k].server_name); ping_requests[k].port = 21; if (pthread_create(&ping_threads[j], NULL, (void *) &tcp_ping, (void *) (&ping_requests[k])) != 0) proz_die("Error: Not enough system resources" "to create thread!\n"); k++; } k -= num_left; for (j = 0; j < num_left; j++) { /*Wait till the end of each thread. */ pthread_join(ping_threads[j], NULL); /*Wait till the end of each thread. */ pthread_join(ping_threads[j], NULL); if (ping_requests[k].err == PINGOK) { pthread_mutex_lock(&request->access_mutex); request->mirrors[k].milli_secs = (ping_requests[k].ping_time.tv_sec * 1000) + (ping_requests[k].ping_time.tv_usec / 1000); request->mirrors[k].status = RESPONSEOK; pthread_mutex_unlock(&request->access_mutex); } else { pthread_mutex_lock(&request->access_mutex); request->mirrors[k].status = NORESPONSE; pthread_mutex_unlock(&request->access_mutex); } k++; } pthread_mutex_lock(&request->access_mutex); request->mass_ping_running = FALSE; pthread_mutex_unlock(&request->access_mutex);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -