📄 host.c
字号:
/* * Copyright (c) 1999 Caucho Technology. All rights reserved. * * Caucho Technology permits redistribution, modification and use * of this file in source and binary form ("the Software") under the * Caucho Developer Source License ("the License"). In particular, the following * conditions must be met: * * 1. Each copy or derived work of the Software must preserve the copyright * notice and this notice unmodified. * * 2. Redistributions of the Software in source or binary form must include * an unmodified copy of the License, normally in a plain ASCII text * * 3. The names "Resin" or "Caucho" are trademarks of Caucho Technology and * may not be used to endorse products derived from this software. * "Resin" or "Caucho" may not appear in the names of products derived * from this software. * * 4. Caucho Technology requests that attribution be given to Resin * in any manner possible. We suggest using the "Resin Powered" * button or creating a "powered by Resin(tm)" link to * http://www.caucho.com for each page served by Resin. * * This Software is provided "AS IS," without a warranty of any kind. * ALL EXPRESS OR IMPLIED REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. * CAUCHO TECHNOLOGY AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE OR ANY THIRD PARTY AS A RESULT OF USING OR * DISTRIBUTING SOFTWARE. IN NO EVENT WILL CAUCHO OR ITS LICENSORS BE LIABLE * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF HE HAS BEEN ADVISED OF THE POSSIBILITY * OF SUCH DAMAGES. * * @author Scott Ferguson * * $Id: mod_caucho.c,v 1.18 1999/12/02 17:02:03 ferg Exp $ */#include "cse.h"/** * Decodes the first 3 characters of the session to see which * JVM owns it. */static intdecode_session(char *session){ int value = 0; int i; for (i = 2; i >= 0; i--) { int code = session[i]; if (code >= 'a' && code <= 'z') value = 64 * value + code - 'a'; else if (code >= 'A' && code <= 'Z') value = 64 * value + code - 'A' + 26; else if (code >= '0' && code <= '9') value = 64 * value + code - 'A' + 52; else if (code == '_') value = 64 * value + 62; else if (code == '/') value = 64 * value + 63; else return -1; } if (i > -1) return -1; else return value;}intcse_session_from_string(char *source, char *cookie){ char *match = strstr(source, cookie); if (match) return decode_session(match + strlen(cookie)); return -1;}/** * Adds a new host to the configuration */voidcse_add_host_int(config_t *config, const char *hostname, int port, int is_backup){ struct hostent *hostent; srun_t *srun; if (config->srun_size == 1 && ! config->srun_list[0].hostname) config->srun_size = 0; // Resize if too many hosts. if (config->srun_size >= config->srun_capacity) { int capacity = config->srun_capacity; srun_t *srun_list; if (capacity == 0) capacity = 4; srun_list = (srun_t *) cse_alloc(config, 2 * capacity * sizeof(srun_t)); memset(srun_list, 0, 2 * capacity * sizeof(srun_t)); if (config->srun_list) memcpy(srun_list, config->srun_list, capacity * sizeof(srun_t)); config->srun_capacity = 2 * capacity; cse_free(config, config->srun_list); config->srun_list = srun_list; } hostent = gethostbyname(hostname); if (hostent && hostent->h_addr) { srun = &config->srun_list[config->srun_size]; srun->hostname = cse_strdup(config, hostname); srun->host = (struct in_addr *) cse_alloc(config, sizeof (struct in_addr)); memcpy(srun->host, hostent->h_addr, sizeof(struct in_addr)); srun->port = port; srun->is_backup = is_backup; srun->open_sock = -1; srun->sock = -1; /* * XXX: for dynamic srun * srun->session = cse_query_session(config, srun, config->pool); */ srun->session = config->srun_size; config->srun_size++; } else { cse_error(config, "CSE cannot find host %s\n", hostname); }}/** * Select a client JVM randomly. */static intrandom_host(char *ip, int requestTime){ int host = time * 23 + g_count++; for (; *ip; ip++) { host = 23 * host + *ip; } if (host < 0) return -host; else return host;}static voidcse_close(stream_t *s, char *msg){ LOG("close %d %s\n", s->socket, msg); close(s->socket); if (s->srun) { s->srun->open_sock = -1; s->srun->sock = -1; } s->socket = -1;}static intcse_reuse(stream_t *s, config_t *config, srun_t *srun, int request_time){ memset(s, 0, sizeof(*s)); s->pool = r->pool; s->config = config; s->write_length = 0; s->read_length = 0; s->read_offset = 0; s->socket = srun->sock; s->srun = srun; srun->is_dead = 0; srun->open_sock = srun->sock; srun->sock = -1; srun->last_time = request_time; LOG("reopen %d\n", s->socket);}static voidcse_recycle(stream_t *s){ if (g_srun_keepalive) { if (s->srun && s->socket >= 0) { s->srun->sock = s->socket; s->srun->open_sock = -1; LOG("reuse %d\n", s->srun->sock); } else if (s->srun && s->srun->open_sock >= 0) { LOG("close2 %d\n", s->srun->open_sock); close(s->srun->open_sock); s->srun->open_sock = -1; } } else { if (s->socket >= 0) close(s->socket); if (s->srun) s->srun->open_sock = -1; }}static intopen_connection(stream_t *s, config_t *config, int sessionIndex, char *ip, int requestTime){ int sessionIndex; int size; int i; int host; int incr; size = config->srun_size; if (size < 1) size = 1; if (sessionIndex < 0) { host = random_host(ip, requestTime) % size; } else { for (host = 0; host < size; host++) { if (config->srun_list[host].session == sessionIndex) break; } if (host == size) { host = random_host(ip, requestTime) % size; } } if (host < 0) host = -host; incr = 2 * (host & 1) - 1; // XXX: if the session belongs to a host, we should retry for a few seconds? for (i = 0; i < size; i++) { srun_t *srun = config->srun_list + (host + i * (incr + size)) % size; if (sessionIndex < 0 && srun->is_backup) { } else if (srun->sock > 0 && srun->last_time + LIVE_TIME >= r->request_time) { cse_reuse(s, config, srun, r); return 1; } else if (srun->is_dead && size > 0 && srun->last_time + DEAD_TIME >= r->request_time && config->srun_size > 1) { } else if (cse_open(s, config, srun, r->pool, r->server)) { s->srun = srun; srun->is_dead = 0; srun->last_time = r->request_time; return 1; } else { srun->is_dead = 1; srun->last_time = r->request_time; } } // Okay, the primaries failed. So try the secondaries. for (i = 0; i < size; i++) { srun_t *srun = config->srun_list + (host + i * (incr + size)) % size; if (srun->sock > 0 && srun->last_time + LIVE_TIME >= r->request_time) { cse_reuse(s, config, srun, r); return 1; } else if (cse_open(s, config, srun, r->pool, r->server)) { s->srun = srun; srun->is_dead = 0; srun->last_time = r->request_time; return 1; } else { srun->is_dead = 1; srun->last_time = r->request_time; } } connection_error(config, config->srun_list, r); return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -