int winsock_init(void) { WORD wVersionRequested; WSADATA wsaData; int rc; wVersionRequested = MAKEWORD(2, 0); if ( (rc = WSAStartup(wVersionRequested, &wsaData)) != 0 ) { my_xlog(LOG_SEVERE, "winsock_init(): Can't init WinSock environment: %d", rc); return(-1); } if ( LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) { my_xlog(LOG_SEVERE, "winsock_init(): Current WinSock version is %d.%d. Version %d.%d required.", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion), LOBYTE(wVersionRequested), HIBYTE(wVersionRequested)); WSACleanup(); return(-1); } my_xlog(LOG_PRINT, "winsock_init(): %s %s\n", wsaData.szDescription, wsaData.szSystemStatus); return(0); }
static int downgrade(struct request *rq, struct mem_obj *obj) { int res = 0; char *transfer_encoding = NULL; #if defined(HAVE_ZLIB) char *content_encoding = NULL; #endif /* HAVE_ZLIB */ if ( (rq->http_major < obj->httpv_major) || (rq->http_minor < obj->httpv_minor) ) { res |= DOWNGRADE_ANSWER; if ( obj->headers ) transfer_encoding = attr_value(obj->headers, "Transfer-Encoding"); if ( transfer_encoding && !strncasecmp("chunked", transfer_encoding, 7)) { my_xlog(OOPS_LOG_HTTP|OOPS_LOG_DBG, "downgrade(): Turn on Chunked Gateway.\n"); res |= UNCHUNK_ANSWER; } } #if defined(HAVE_ZLIB) content_encoding = attr_value(obj->headers, "Content-Encoding"); if ( content_encoding && !strncasecmp(content_encoding, "gzip", 4) ) { /* we ungzip if useragent won't accept gzip */ char *ua_accept = attr_value(rq->av_pairs, "accept-encoding"); if ( !ua_accept || !(strstr(ua_accept, "gzip")) ) res |= UNGZIP_ANSWER; } #endif return(res); }
/* read with timeout */ int readt(int so, char* buf, int len, int tmo) { int to_read = len, sr, got; char *p = buf; struct pollarg pollarg; if ( so < 0 ) return(0); if ( len <= 0 ) return(0); pollarg.fd = so; pollarg.request = FD_POLL_RD; sr = poll_descriptors(1, &pollarg, tmo*1000); if ( sr < 0 ) { // if ( ERRNO == EINTR ) return(readed); return(sr); } if ( sr == 0 ) { /* timeout */ return(-2); } if ( IS_HUPED(&pollarg) ) return(0); /* have somethng to read */ got = recv(so, p, to_read,0); if ( got == 0 ) { my_xlog(OOPS_LOG_DBG|OOPS_LOG_INFORM, "readt(): got: %d, tmo: %d, to_read: %d\n", got, tmo, to_read); } return(got); }
long pwrite(HANDLE fh, void *buf, size_t nbyte, off_t offset) { DWORD NumberOfBytesWrite; OVERLAPPED Overlapped; Overlapped.Offset = offset; Overlapped.OffsetHigh = 0; Overlapped.hEvent = NULL; if ( WriteFile((HANDLE)fh, buf, (DWORD)nbyte, &NumberOfBytesWrite, &Overlapped) == 0 ) { if ( ERRNO == ERROR_IO_PENDING ) { if ( GetOverlappedResult(fh, &Overlapped, &NumberOfBytesWrite, TRUE) == 0 ) goto err; } else goto err; } done: set_errno(0); return(NumberOfBytesWrite); err: my_xlog(LOG_SEVERE, "pwrite(): WriteFile(): ERRNO = (%d): %m\n", ERRNO); return(-1); }
long pread(HANDLE fh, void *buf, size_t nbyte, off_t offset) { DWORD NumberOfBytesRead; OVERLAPPED Overlapped; if ( nbyte == 0 ) return 0; Overlapped.Offset = offset; Overlapped.OffsetHigh = 0; Overlapped.hEvent = NULL; if ( ReadFile(fh, buf, (DWORD)nbyte, &NumberOfBytesRead, &Overlapped) == 0 ) { if ( ERRNO == ERROR_IO_PENDING ) { if ( GetOverlappedResult(fh, &Overlapped, &NumberOfBytesRead, TRUE) == 0 ) goto err; } else goto err; } done: set_errno(0); return(NumberOfBytesRead); err: if ( ERRNO == ERROR_HANDLE_EOF ) goto done; my_xlog(LOG_SEVERE, "pread(): ReadFile(): ERRNO = (%d): %m\n", ERRNO); return(-1); }
int fcntl(int fd, int cmd, ...) { va_list args; int arg = 0; int res; switch(cmd) { case F_GETFL: res = 0; my_xlog(LOG_DBG, "fcntl(F_GETFL): fd = %d, res = %d\n", fd, res); goto done; case F_SETFL: va_start(args, cmd); arg = va_arg(args, int); va_end(args); if (arg & O_NONBLOCK) { unsigned long nonb = 1; if ( (res = ioctlsocket(fd, FIONBIO, &nonb)) != 0 ) { my_xlog(LOG_SEVERE, "fcntl(F_SETFL): ioctlsocket(fd = %d, O_NONBLOCK): res = %d, nonb = %d, %m\n", fd, res, nonb); res = -1; goto done; } my_xlog(LOG_DBG, "fcntl(F_SETFL): ioctlsocket(fd = %d, O_NONBLOCK): res = %d, nonb = %d\n", fd, res, nonb); goto done; } if (arg & O_BLOCK) { unsigned long nonb = 0; if ( (res = ioctlsocket(fd, FIONBIO, &nonb)) != 0 ) { my_xlog(LOG_SEVERE, "fcntl(F_SETFL): ioctlsocket(fd = %d, O_BLOCK): res = %d, nonb = %d, %m\n", fd, res, nonb); res = -1; goto done; } my_xlog(LOG_DBG, "fcntl(F_SETFL): ioctlsocket(fd = %d, O_BLOCK): res = %d, nonb = %d\n", fd, res, nonb); goto done; } set_errno(ERROR_NOT_SUPPORTED); res = -1; my_xlog(LOG_DBG, "fcntl(F_SETFL): ioctlsocket(fd = %d, %d): res = %d, %m\n", fd, arg, res); goto done; default: set_errno(ERROR_NOT_SUPPORTED); res = -1; my_xlog(LOG_DBG, "fcntl(%d): fd = %d, res = %d, %m\n", cmd, fd, res); goto done; } done: return res; }
int sess_traffic_load(struct request *rq) { int cbytes, bw; if ( !rq || !(bw = rq->sess_bw) ) return(0); cbytes = rq->s0_sent; my_xlog(OOPS_LOG_SEVERE, "Session bw: %d\n", (cbytes*100)/bw); return((cbytes*100)/bw); }
int winsock_shutdown(void) { int rc; if ( (rc = WSACleanup()) != 0 ) { my_xlog(LOG_SEVERE, "winsock_shutdown(): Can't shutdown WinSock environment: %d\n", rc); return(-1); } return(0); }
inline static int add_header_av(char* avtext, struct mem_obj *obj) { struct av *new_t = NULL, *next; char *attr = avtext, *sp = avtext, *val, holder; char *new_attr = NULL, *new_val = NULL; char nullstr[1]; if ( *sp == 0 ) return(-1); while( *sp && IS_SPACE(*sp) ) sp++; while( *sp && !IS_SPACE(*sp) && (*sp != ':') ) sp++; if ( !*sp ) { my_xlog(OOPS_LOG_NOTICE|OOPS_LOG_DBG|OOPS_LOG_INFORM, "add_header_av(): Invalid header string: '%s'\n", avtext); nullstr[0] = 0; sp = nullstr; } if ( *sp == ':' ) sp++; holder = *sp; *sp = 0; if ( !strlen(attr) ) return(-1); new_t = (struct av *)xmalloc(sizeof(*new_t), "add_header_av(): for av pair"); if ( !new_t ) goto failed; new_attr = (char *)xmalloc( strlen(attr)+1, "add_header_av(): for new_attr" ); if ( !new_attr ) goto failed; strcpy(new_attr, attr); *sp = holder; val = sp; while( *val && IS_SPACE(*val) ) val++; /*if ( !*val ) goto failed;*/ new_val = (char *)xmalloc( strlen(val) + 1, "add_header_av(): for new_val"); if ( !new_val ) goto failed; strcpy(new_val, val); new_t->attr = new_attr; new_t->val = new_val; new_t->next = NULL; if ( !obj->headers ) { obj->headers = new_t; } else { next = obj->headers; while (next->next) next=next->next; next->next=new_t; } return(0); failed: *sp = holder; if ( new_t ) free(new_t); if ( new_attr ) free(new_attr); if ( new_val ) free(new_val); return(-1); }
HANDLE open_storage(const char *path, int oflag, /* mode_t mode */...) { HANDLE fHandle; DWORD DesiredAccess = 0; SECURITY_ATTRIBUTES SecurityAttributes; DWORD CreationDistribution = OPEN_EXISTING; if ( oflag & O_CREAT ) CreationDistribution = OPEN_ALWAYS; if ( oflag & O_RDONLY ) DesiredAccess = GENERIC_READ; if ( oflag & O_RDWR ) DesiredAccess = GENERIC_READ|GENERIC_WRITE; SecurityAttributes.lpSecurityDescriptor = NULL; SecurityAttributes.bInheritHandle = TRUE; if ( (fHandle = CreateFile(path, DesiredAccess, FILE_SHARE_READ|FILE_SHARE_WRITE, &SecurityAttributes, CreationDistribution, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, /* FILE_FLAG_WRITE_THROUGH,*/ /* FILE_FLAG_NO_BUFFERING */ /* FILE_FLAG_RANDOM_ACCESS */ NULL)) == INVALID_HANDLE_VALUE ) { my_xlog(LOG_SEVERE, "open_storage(): CreateFile(): ERRNO = (%d): %m\n", ERRNO); return((HANDLE)-1); } return(fHandle); }
static int load_body(struct request *rq,struct mem_obj *obj) { // char *answer = NULL; // struct server_answ answ_state; struct pollarg pollarg[2]; //struct av *header = NULL; int r=0; unsigned body_size=obj->container->used; char answer[ANSW_SIZE+1]; // unsigned c_time=rq->client->set_time(0); // unsigned s_time=rq->server->set_time(0); if(obj->container && obj->container->used>0) { if(rq->server->send(obj->container->data,obj->container->used)<=0) { //printf("cann't send to client\n"); goto error; } } if(obj->content_length<=0) { //if content-length is zero ,we don't cache it //printf("the content-length is zero\n"); //pump_data(rq->server->get_socket(),rq->client->get_socket()); if(create_select_pipe(rq->server,rq->client,conf.time_out[HTTP],0,-1)==-2) r=1; goto error; } pollarg[0].fd = rq->client->get_socket(); pollarg[0].request = FD_POLL_RD; pollarg[1].fd = rq->server->get_socket(); pollarg[1].request = FD_POLL_RD; forever() { if((r = poll_descriptors(2, &pollarg[0], conf.time_out[HTTP]*1000))<=0) { klog(DEBUG_LOG,"poll descriptors is error in file %s line %d\n",__FILE__,__LINE__); // printf("1\n"); goto done; } if(IS_READABLE(&pollarg[1]) || IS_HUPED(&pollarg[1])) { klog(DEBUG_LOG,"client close the connection in body\n"); // printf("2\n"); goto done; } if(IS_READABLE(&pollarg[0])) r = rq->client->recv_t(answer, ANSW_SIZE,0); else { klog(DEBUG_LOG,"unknow error is happen\n"); // printf("3\n"); goto done; } if ( r <=0 ) goto done; body_size += r; if(body_size>obj->content_length) { // destroy_obj(obj,0); if(rq->server->send(answer,r)<0) goto error; if(create_select_pipe(rq->server,rq->client,conf.time_out[HTTP],0,-1)==-2) r=1; goto error; } /* store data in hot_buff */ /* if(writet(so,answer,r,READ_ANSW_TIMEOUT)<=0) goto error; */ if(rq->server->send(answer,r)<=0) { // printf("cann't send to client\n"); goto error; } if ( store_in_chain(answer, r, obj) ) { my_xlog(OOPS_LOG_SEVERE, "fill_mem_obj(): Can't store.\n"); obj->flags |= FLAG_DEAD; // printf("cann't store in chain\n"); goto error; } } done: // rq->server->set_time(s_time); // rq->client->set_time(c_time); if(body_size<=0 || body_size!=obj->content_length) { //数据不完整,不保存 //printf("body_size != content_length\n"); goto error; } return 1; error: // rq->server->set_time(s_time); // rq->client->set_time(c_time); SET(obj->flags,FLAG_DEAD); return r; }
/* if ( (r < 0) && (ERRNO == EAGAIN) ) goto sel_again; * / if ( r <= 0 ) return so; r = write(server_so, b, r);//, conf.time_out[HTTP]); if ( r <= 0 ) return server_so;// goto done; } } done: return -1; } */ inline static void analyze_header(char *p, struct server_answ *a) { char *t; // my_xlog(OOPS_LOG_HTTP|OOPS_LOG_DBG, "analyze_header(): ---> `%s'.\n", p); if ( !a->status_code ) { /* check HTTP/X.X XXX */ if ( !strncasecmp(p, "HTTP/", 5) ) { int httpv_major, httpv_minor; if ( sscanf(p+5, "%d.%d", &httpv_major, &httpv_minor) == 2 ) { a->httpv_major = httpv_major; a->httpv_minor = httpv_minor; } t = strchr(p, ' '); if ( !t ) { my_xlog(OOPS_LOG_NOTICE|OOPS_LOG_DBG|OOPS_LOG_INFORM, "analyze_header(): Wrong_header: %s\n", p); return; } a->status_code = atoi(t); my_xlog(OOPS_LOG_DBG, "analyze_header(): Status code: %d\n", a->status_code); } return; } if ( !strncasecmp(p, "Content-length: ", 16) ) { char *x; /* length */ x=p + 16; /* strlen("content-length: ") */ while( *x && IS_SPACE(*x) ) x++; a->content_len = atoi(x); return; } if ( !strncasecmp(p, "Date: ", 6) ) { char *x; /* length */ x=p + 6; /* strlen("date: ") */ while( *x && IS_SPACE(*x) ) x++; a->times.date = global_sec_timer; if (http_date(x, &a->times.date) ) my_xlog(OOPS_LOG_DBG|OOPS_LOG_INFORM, "analyze_header(): Can't parse date: %s\n", x); return; } if ( !strncasecmp(p, "Last-Modified: ", 15) ) { char *x; /* length */ x=p + 15; /* strlen("date: ") */ while( *x && IS_SPACE(*x) ) x++; if (http_date(x, &a->times.last_modified) ) my_xlog(OOPS_LOG_DBG|OOPS_LOG_INFORM, "analyze_header(): Can't parse date: %s\n", x); else a->flags |= ANSW_LAST_MODIFIED; return; } if ( !strncasecmp(p, "Pragma: ", 8) ) { char *x; /* length */ x=p + 8; /* strlen("Pragma: ") */ if ( strstr(x, "no-cache") ) a->flags |= ANSW_NO_STORE; return; } if ( !strncasecmp(p, "Age: ", 5) ) { char *x; /* length */ x=p + 5; /* strlen("Age: ") */ a->times.age = atoi(x); return; } if ( !strncasecmp(p, "Cache-Control: ", 15) ) { char *x; /* length */ x=p + 15; /* strlen("Cache-Control: ") */ while( *x && IS_SPACE(*x) ) x++; if ( strstr(x, "no-store") ) a->flags |= ANSW_NO_STORE; if ( strstr(x, "no-cache") ) a->flags |= ANSW_NO_STORE; if ( strstr(x, "private") ) a->flags |= ANSW_NO_STORE; if ( strstr(x, "must-revalidate") ) a->flags |= ANSW_MUST_REVALIDATE; if ( !strncasecmp(x, "proxy-revalidate", 15) ) a->flags |= ANSW_PROXY_REVALIDATE; if ( sscanf(x, "max-age = %d", (int*)&a->times.max_age) == 1 ) a->flags |= ANSW_HAS_MAX_AGE; } if ( !strncasecmp(p, "Connection: ", 12) ) { char *x; /* length */ x = p + 12; /* strlen("Connection: ") */ while( *x && IS_SPACE(*x) ) x++; if ( !strncasecmp(x, "keep-alive", 10) ) a->flags |= ANSW_KEEP_ALIVE; if ( !strncasecmp(x, "close", 5) ) a->flags &= ~ANSW_KEEP_ALIVE; } if ( !TEST(a->flags, ANSW_HAS_EXPIRES) && !strncasecmp(p, "Expires: ", 9) ) { char *x; /* length */ x = p + 9; /* strlen("Expires: ") */ while( *x && IS_SPACE(*x) ) x++; a->times.expires = time(NULL); if (http_date(x, &a->times.expires)) { my_xlog(OOPS_LOG_DBG|OOPS_LOG_INFORM, "analyze_header(): Can't parse date: %s\n", x); return; } a->flags |= ANSW_HAS_EXPIRES; return; } }
void * statistics(void *arg) { struct group *group; struct peer *peer; struct oops_stat temp_stat; int counter = 0, i; int hits = 0, reqs = 0; int purge = PURGE_INTERVAL; ip_hash_entry_t *he, *next_he; if ( arg ) return (void *)0; my_xlog(OOPS_LOG_NOTICE|OOPS_LOG_DBG|OOPS_LOG_INFORM, "Statistics started.\n"); bzero(&oops_stat, sizeof(oops_stat)); start_time = oops_stat.timestamp0 = oops_stat.timestamp = time(NULL); forever() { global_sec_timer = time(NULL); tick_modules(); if ( ++counter == 60 ) { /* once per minute */ LOCK_STATISTICS(oops_stat); memcpy(&temp_stat, &oops_stat, sizeof(oops_stat)); oops_stat.requests_http1 = oops_stat.requests_http0; oops_stat.hits1 = oops_stat.hits0; oops_stat.requests_http0 = 0; oops_stat.hits0 = 0; oops_stat.timestamp0 = oops_stat.timestamp; oops_stat.timestamp = global_sec_timer; oops_stat.drops0 = 0; oops_stat.requests_icp1 = oops_stat.requests_icp0; oops_stat.requests_icp0 = 0; if ( oops_stat.requests_http1 > oops_stat.requests_http0_max ) oops_stat.requests_http0_max = oops_stat.requests_http1; if ( oops_stat.requests_icp1 > oops_stat.requests_icp0_max ) oops_stat.requests_icp0_max = oops_stat.requests_icp1; if ( oops_stat.hits0_max > oops_stat.hits1 ) oops_stat.hits0_max = oops_stat.hits1; if ( oops_stat.clients > oops_stat.clients_max ) oops_stat.clients_max = oops_stat.clients; #if HAVE_GETRUSAGE memcpy(&oops_stat.rusage0, &oops_stat.rusage, sizeof(oops_stat.rusage)); getrusage(RUSAGE_SELF, &oops_stat.rusage); #endif UNLOCK_STATISTICS(oops_stat); reqs = temp_stat.requests_http0; hits = temp_stat.hits0; my_xlog(OOPS_LOG_NOTICE|OOPS_LOG_DBG|OOPS_LOG_INFORM, "statistics(): clients : %d\n", temp_stat.clients); my_xlog(OOPS_LOG_NOTICE|OOPS_LOG_DBG|OOPS_LOG_INFORM, "statistics(): http_requests: %d\n", temp_stat.requests_http); my_xlog(OOPS_LOG_NOTICE|OOPS_LOG_DBG|OOPS_LOG_INFORM, "statistics(): icp_requests : %d\n", temp_stat.requests_icp); my_xlog(OOPS_LOG_NOTICE|OOPS_LOG_DBG|OOPS_LOG_INFORM, "statistics(): req_rate : %d/s\n", temp_stat.requests_http0/60); if ( reqs ) my_xlog(OOPS_LOG_NOTICE|OOPS_LOG_DBG|OOPS_LOG_INFORM, "statistics(): hits_rate : %d%%\n", (hits*100)/reqs); else my_xlog(OOPS_LOG_NOTICE|OOPS_LOG_DBG|OOPS_LOG_INFORM, "statistics(): hits_rate : 0%%\n"); counter = 0; } RDLOCK_CONFIG; peer = peers; while ( peer ) { if ( !peer->icp_port ) { /* this is not icp peer - different up/down ideology */ peer = peer->next; continue; } if ( ABS(peer->last_recv - peer->last_sent) > peer_down_interval ) { peer->state |= PEER_DOWN ; } else { peer->state &= ~PEER_DOWN ; } peer = peer->next; } /* run over all groups and move statistics */ group = groups ; if ( group ) { while ( group ) { /* my_xlog(OOPS_LOG_DBG, "statistics(): transfer : %d bytes/sec\n", MID(bytes)); */ pthread_mutex_lock(&group->group_mutex); group->cs_total.bytes += group->cs0.bytes; group->cs_total.requests += group->cs0.requests; group->cs2 = group->cs1; group->cs1 = group->cs0; bzero((void*)&group->cs0, sizeof(group->cs0)); pthread_mutex_unlock(&group->group_mutex); /* remove stale dstdomain cache entries */ if ( group->dstdomain_cache ) { if ( purge <= 0 ) { if ( hash_operate(group->dstdomain_cache, purge_old_dstd) ) purge = PURGE_INTERVAL; } else purge--; } group = group->next; } } for (i=0; i<IP_HASH_SIZE; i++) { pthread_mutex_lock(&ip_hash[i].lock); he = ip_hash[i].link; while ( he ) { pthread_mutex_lock(&he->lock); next_he = he->next; he->traffic2 = he->traffic1; he->traffic1 = he->traffic0; he->traffic0 = 0; pthread_mutex_unlock(&he->lock); if ( !he->refcount ) { if ( global_sec_timer - he->access >= 10 ) { /* unlink and free */ if ( !he->prev ) { ip_hash[i].link = he->next; } else { he->prev->next = he->next; } if ( he->next ) he->next->prev = he->prev; pthread_mutex_destroy(&he->lock); free(he); } } he = next_he; } pthread_mutex_unlock(&ip_hash[i].lock); } if ( !counter && statisticslog[0] ) { FILE *statl = fopen(statisticslog, "w"); if ( statl ) { fprintf(statl,"clients : %d\n", (unsigned)temp_stat.clients); fprintf(statl,"uptime : %ld sec.\n", (utime_t)(global_sec_timer-start_time)); fprintf(statl,"http_requests: %d\n", (unsigned)temp_stat.requests_http); fprintf(statl,"http_hits : %d\n", (unsigned)temp_stat.hits); fprintf(statl,"icp_requests : %d\n", (unsigned)temp_stat.requests_icp); fprintf(statl,"req_rate : %d/s\n", (unsigned)(temp_stat.requests_http0/60)); if ( reqs ) fprintf(statl,"hits_rate : %d%%\n", (hits*100)/reqs); else fprintf(statl,"hits_rate : 0%%\n"); fprintf(statl,"free_space : %u%%\n", (unsigned)temp_stat.storages_free); fclose(statl); } } UNLOCK_CONFIG; my_sleep(1); } }