Beispiel #1
0
void ICACHE_FLASH_ATTR acl_show(uint8_t acl_no, uint8_t *buf)
{
int i;
acl_entry *my_entry;
uint8_t line[80], addr1[21], addr2[21], port1[6], port2[6];

    buf[0] = 0;

    if (acl_no >= MAX_NO_ACLS)
	return;

    for(i=0; i<acl_freep[acl_no]; i++) {
	my_entry = &acl[acl_no][i];
	addr2str(addr1, my_entry->src, my_entry->s_mask);
	port2str(port1, my_entry->s_port);
	addr2str(addr2, my_entry->dest, my_entry->d_mask);
	port2str(port2, my_entry->d_port);
	if (my_entry->proto != 0)
	    os_sprintf(line, "%s %s:%s %s:%s %s%s (%d hits)\r\n",
		my_entry->proto==IP_PROTO_TCP?"TCP":"UDP", 
		addr1, port1, addr2, port2,
		(my_entry->allow & ACL_ALLOW)?"allow":"deny",
		(my_entry->allow & ACL_MONITOR)?"_monitor":"",
		my_entry->hit_count);
	else 
	    os_sprintf(line, "IP %s %s %s%s (%d hits)\r\n",
		addr1, addr2,
		(my_entry->allow & ACL_ALLOW)?"allow":"deny",
		(my_entry->allow & ACL_MONITOR)?"_monitor":"",
		my_entry->hit_count);
        os_memcpy(&buf[os_strlen(buf)], line, os_strlen(line)+1);
    }
}
Beispiel #2
0
int cf_msg_logger::log(const char* buf, int len,
			 sockaddr_storage* src_ip,
			 sockaddr_storage* dst_ip,
			 cstring method, int reply_code)
{
  string src = addr2str(src_ip);
  string dst = addr2str(dst_ip);

  AmLock _l(fd_mut);

  write_src_dst(src);
  write_src_dst(dst);
  
  string what = c2stlstr(method);
  if(reply_code > 0) {
    what = int2str(reply_code) + " / " + what;
  }

  WRITE_CSTSTR("<call src='");
  WRITE_STLSTR(src);
  WRITE_CSTSTR("' dst='");
  WRITE_STLSTR(dst);
  WRITE_CSTSTR("' desc='");
  WRITE_STLSTR(what);
  WRITE_CSTSTR("'>\n");

  if(write(buf,len) != len) return -1;

  WRITE_CSTSTR("</call>\n");
 
  return 0;
}
static void ipv4(const char *filename, const char *label) {
    FILE *fp = fopen(filename, "r");
    if (fp == NULL) {
        return;
    }
    char buf[BUFSIZ];
    fgets(buf, BUFSIZ, fp);
    while (fgets(buf, BUFSIZ, fp)){
        char lip[ADDR_LEN];
        char rip[ADDR_LEN];
        iaddr laddr, raddr;
        unsigned lport, rport, state, txq, rxq, num;
        int n = sscanf(buf, " %d: %x:%x %x:%x %x %x:%x",
                       &num, &laddr.u, &lport, &raddr.u, &rport,
                       &state, &txq, &rxq);
        if (n == 8) {
            addr2str(AF_INET, &laddr, lport, lip);
            addr2str(AF_INET, &raddr, rport, rip);

            printf("%4s  %6d %6d %-22s %-22s %s\n",
                   label, rxq, txq, lip, rip,
                   state2str(state));
        }
    }
    fclose(fp);
}
Beispiel #4
0
/**
 * Initialize the IB connection.
 *
 * Initializes an IronBee connection from a ATS continuation
 *
 * @param[in] iconn IB connection
 * @param[in] ssn Session context data
 *
 * @returns status
 */
static ib_status_t ironbee_conn_init(
    tsib_ssn_ctx *ssndata)
{
    assert(ssndata != NULL);
    const struct sockaddr *addr;
    int                    port;
    ib_conn_t             *iconn = ssndata->iconn;

    /* remote ip */
    addr = TSHttpTxnClientAddrGet(ssndata->txnp);
    addr2str(addr, ssndata->remote_ip, &port);

    iconn->remote_ipstr = ssndata->remote_ip;

    /* remote port */
    iconn->remote_port = port;

    /* local end */
    addr = TSHttpTxnIncomingAddrGet(ssndata->txnp);

    addr2str(addr, ssndata->local_ip, &port);

    iconn->local_ipstr = ssndata->local_ip;

    /* local_port */
    iconn->local_port = port;

    return IB_OK;
}
Beispiel #5
0
static ib_status_t ironbee_conn_init(ib_engine_t *ib,
                                   ib_conn_t *iconn, void *cbdata)
{
  /* when does this happen? */
  ib_status_t rc;
  const struct sockaddr *addr;
  int port;

  TSCont contp = iconn->pctx;
  ib_ssn_ctx* data = TSContDataGet(contp);
//  ib_clog_debug(....);

  /* remote ip */
  addr = TSHttpTxnClientAddrGet(data->txnp);

  addr2str(addr, data->remote_ip, &port);

  iconn->remote_ipstr = data->remote_ip;
  rc = ib_data_add_bytestr(iconn->dpi,
                             "remote_ip",
                             (uint8_t *)iconn->remote_ipstr,
                             strlen(data->remote_ip),
                             NULL);
    if (rc != IB_OK) {
        return rc;
    }

  /* remote port */
  iconn->remote_port = port;
    rc = ib_data_add_num(iconn->dpi, "remote_port", port, NULL);
    if (rc != IB_OK) {
        return rc;
    }

  /* local end */
  addr = TSHttpTxnIncomingAddrGet(data->txnp);

  addr2str(addr, data->local_ip, &port);

    iconn->local_ipstr = data->local_ip;
    rc = ib_data_add_bytestr(iconn->dpi,
                             "local_ip",
                             (uint8_t *)iconn->local_ipstr,
                             strlen(data->local_ip),
                             NULL);
    if (rc != IB_OK) {
        return rc;
    }

    /* local_port */
    iconn->local_port = port;
    rc = ib_data_add_num(iconn->dpi, "local_port", port, NULL);
    if (rc != IB_OK) {
        return rc;
    }
  return IB_OK;
}
Beispiel #6
0
int handle_lsync(connection *con, uint32_t size, void* data) {
    learner_sync_msg* msg = (learner_sync_msg*)data;
    char ipstr[32];

    acceptor_record* rec;
    int i;
    for(i=0; i<msg->count ;i++){

    	uint32_t instance_id = msg->ids[i];
        //Lookup
        rec = &acc.instance_cache[GET_ACC_INDEX(instance_id)];
    
        //Found record in memory
        if (instance_id == rec->iid) {
            //A value was accepted
            if (rec->value != NULL) {
                L_DEBUG("answering to lsync for instance %d\n", instance_id);
                return send_learn_message(addr2str(ipstr, con->remoteaddr), con->remoteport, rec);
            }
            //No value was accepted
            L_DEBUG("ignoring lsync for instance %d, record present but no value accepted\n", instance_id);
            return 0;
        }
    
        //Record was overwritten in acceptor array
        //We must scan the logfile before answering
        if (instance_id < rec->iid) {
            rec = stablestorage_get_record(instance_id);

            //A record was found, we accepted something
            if (rec != NULL) {
                L_DEBUG("answering to lsync for instance %d [info from disk]\n", instance_id);
                send_learn_message(addr2str(ipstr, con->remoteaddr), con->remoteport, rec);
                free(rec->value);
                free(rec);
            } else {
                //Nothing from disk, nothing accepted
                L_DEBUG("ignoring lsync for instance %d, no value accepted [info from disk]\n", instance_id);
            }
    
            return 0;
        }
    
        //Record not found in acceptor array
        //Nothing was accepted
        L_DEBUG("ignoring lsync for instance %d, no info is available\n", instance_id);
        return 0;

    }

}
Beispiel #7
0
/*
 * Answer if this is an AXFR or IXFR query.
 */
query_state_type
answer_axfr_ixfr(struct nsd *nsd, struct query *q)
{
	struct acl_options *acl = NULL;
	/* Is it AXFR? */
	switch (q->qtype) {
	case TYPE_AXFR:
		if (q->tcp) {
			struct zone_options* zone_opt;
			zone_opt = zone_options_find(nsd->options, q->qname);
			if(!zone_opt ||
			   acl_check_incoming(zone_opt->pattern->provide_xfr, q, &acl)==-1)
			{
				if (verbosity >= 2) {
					char a[128];
					addr2str(&q->addr, a, sizeof(a));
					VERBOSITY(2, (LOG_INFO, "axfr for %s from %s refused, %s",
						dname_to_string(q->qname, NULL), a, acl?"blocked":"no acl matches"));
				}
				DEBUG(DEBUG_XFRD,1, (LOG_INFO, "axfr refused, %s",
					acl?"blocked":"no acl matches"));
				if (!zone_opt) {
					RCODE_SET(q->packet, RCODE_NOTAUTH);
				} else {
					RCODE_SET(q->packet, RCODE_REFUSE);
				}
				return QUERY_PROCESSED;
			}
			DEBUG(DEBUG_XFRD,1, (LOG_INFO, "axfr admitted acl %s %s",
				acl->ip_address_spec, acl->key_name?acl->key_name:"NOKEY"));
			if (verbosity >= 1) {
				char a[128];
				addr2str(&q->addr, a, sizeof(a));
				VERBOSITY(1, (LOG_INFO, "%s for %s from %s",
					(q->qtype==TYPE_AXFR?"axfr":"ixfr"),
					dname_to_string(q->qname, NULL), a));
			}
			return query_axfr(nsd, q);
		}
		/** Fallthrough: AXFR over UDP queries are discarded. */
		/* fallthrough */
	case TYPE_IXFR:
		RCODE_SET(q->packet, RCODE_IMPL);
		return QUERY_PROCESSED;
	default:
		return QUERY_DISCARDED;
	}
}
Beispiel #8
0
/**
 * The function killing an client peer socket file descriptor, modifies
 * global variables fs; the file descriptor set, and fd_max.
 *
 * \param[out] fs       Pointer to file descriptor set
 * \param[out] fd_ax    Pointer  to the highest client file descriptor
 * \param[in]  fd       Client file descriptor
 */
static void server_kill_peer(fd_set *fs, int *fd_max, int fd) {
	char addrstr[INET6_ADDRSTRLEN];
	struct server_peer *p;
	addr_t tmp;
	socklen_t slen;

	/* Print disconnect message */
	memset(&tmp, 0, sizeof tmp);
	slen = (socklen_t)sizeof tmp;
	if (getpeername(fd, (struct sockaddr*)&tmp, &slen) == 0) {
		if (addr2str(&tmp, addrstr) == 0) {
			syslog(LOG_INFO, "server: %s: %d: Disconnected", addrstr, fd);
		} else syslog(LOG_INFO, "server: %d: Disconnected", fd);
	} else syslog(LOG_INFO, "server: %d: Disconnected", fd);
	/* Remove linked list */
	for (p = peers_head.lh_first; p != NULL; p = p->list.le_next) {
		if (p->fd == fd) {
			LIST_REMOVE(p, list);
			free(p);
			break; /* Otherwise for() crashes! */
		}
	}
	/* Close, clear fd set, maybe decrease fd_max */
	if (close(fd) < 0)
		syslog(LOG_ERR, "server: close: %s", strerror(errno));
	unix_fd_clr(fd, fs);
	if (fd == *fd_max)
		(*fd_max)--;
}
Beispiel #9
0
static const char *for_dest(void)
{
	static char addr_area[ADDR_AREA];

	if (dest == own_node())
		return "";
	sprintf(addr_area, " for node %s", addr2str(dest));
	return addr_area;
}
Beispiel #10
0
static const char *for_domain(const char *string, __u32 domain)
{
	static char addr_area[ADDR_AREA];

	if (domain == 0)
		return "";
	sprintf(addr_area, "%s%s", string, addr2str(domain));
	return addr_area;
}
Beispiel #11
0
void set_near() {
	struct near_node *iterator = near_list_head;
	memset(near_str, 0, max_tcp_sock * 6);
	int n = 0;

	while (iterator != NULL) {
		addr2str(near_str + n * 6, iterator->addr.sin_addr.s_addr, iterator->addr.sin_port);	
		iterator = iterator->next;
		n ++;
	}
}
Beispiel #12
0
static void cmd_dest(Stream *chp, int argc, char *argv[]) 
{
  addr_t x;
  if (argc > 0) {
    str2addr(&x, argv[0], false);
    SET_PARAM(DEST, &x);
    chprintf(chp, "Ok\r\n");
  }
  else {
    GET_PARAM(DEST, &x);
    chprintf(chp, "DEST %s\r\n", addr2str(buf, &x));
  } 
}
Beispiel #13
0
static void cmd_mycall(Stream *chp, int argc, char *argv[]) 
{
   addr_t x;
   if (argc > 0) {
      str2addr(&x, argv[0], false);
      SET_PARAM(MYCALL, &x);
      chprintf(chp, "Ok\r\n");
   }
   else {
      GET_PARAM(MYCALL, &x);
      chprintf(chp, "MYCALL %s\r\n", addr2str(buf, &x));
   } 
}
Beispiel #14
0
int
show_breakpoints (void)
{
  struct bp *ptr;

  for (ptr = first_bp_ptr; ptr != NULL; ptr = ptr->next)
    {
      char buf[20];

      addr2str (&ptr->address, buf);
      xprintf ("%s\n", buf);
    }
  
  return 0;
}
Beispiel #15
0
/*
 * Accept and authenticate a new client connection on one of the listening sockets.
 */
static void
server_socket_event(int server_fd, int epfd)
{
    struct epoll_event ev;
    struct sockaddr_storage addr;
    int newfd, opt_enable = 1;
    socklen_t addrlen = sizeof (addr);

    memset(&addr, 0, addrlen);
    newfd =
        accept4(server_fd, (struct sockaddr *)&addr, &addrlen,
                SOCK_NONBLOCK | SOCK_CLOEXEC);
    if (newfd == -1)    /* maybe the connection attempt was aborted early? */
        return;

    /* no need to complain if this setsockopt fails; TCP_NODELAY doesn't exist
       for AF_UNIX sockets. */
    setsockopt(newfd, IPPROTO_TCP, TCP_NODELAY, &opt_enable, sizeof (int));

    if (addr.ss_family == AF_UNIX) {
        /* unix sockets don't have defer_accept, so the auth data might not be
           ready yet. Additionally, as the socket is local, it gets a higher
           level of trust. */
        ev.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET;
        ev.data.ptr = NULL;
        ev.data.fd = newfd;
        if (epoll_ctl(epfd, EPOLL_CTL_ADD, newfd, &ev) == -1) {
            log_msg("Error in epoll_ctl for %s: %s", addr2str(&addr),
                    strerror(errno));
            close(newfd);
            return;
        }
        map_fd_to_client(newfd, &new_connection_dummy);
        return;
    } else
        handle_new_connection(newfd, epfd);
}
Beispiel #16
0
/* full setup for both ipv4 and ipv6 server sockets */
static int
init_server_socket(struct sockaddr *sa)
{
    int fd, opt_enable = 1, defer_seconds = 20;
    socklen_t len;

    fd = socket(sa->sa_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
    if (fd < 0) {
        log_msg("Error creating server socket: %s", strerror(errno));
        return -1;
    }

    /* Enable fast address re-use. Nice to have during development, probably
       irrelevant otherwise. */
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt_enable, sizeof (int));

    switch (sa->sa_family) {
    case AF_INET:
        len = sizeof (struct sockaddr_in);
        break;
    case AF_INET6:
        len = sizeof (struct sockaddr_in6);
        /* Setting the IPV6_V6ONLY socket option allows the ipv6 socket to bind 
           to the same port as the ipv4 socket. Using one socket for each
           protocol is better than using one ipv4-compatible ipv6 socket, as
           that limits the possible ipv6 addresses to ipv4 compatible ones. */
        if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt_enable, sizeof (int))
            == -1)
            log_msg("Failed to set the IPV6_V6ONLY socket option: %s.",
                    strerror(errno));
        break;
    case AF_UNIX:
        len = sizeof (struct sockaddr_un);
        break;

    default:   /* shouldn't ever happen */
        close(fd);
        return -1;
    }

    if (sa->sa_family != AF_UNIX) {
        /* don't accept client connections until there is data */
        if (setsockopt
            (fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &defer_seconds,
             sizeof (int)) == -1)
            log_msg("Failed to set the DEFER_ACCEPT socket option: %s.",
                    strerror(errno));
    }

    if (bind(fd, sa, len) == -1) {
        close(fd);
        log_msg("Error binding server socket (%s): %s", addr2str(sa),
                strerror(errno));
        return -1;
    }

    if (listen(fd, 16) == -1) {
        close(fd);
        log_msg("Error listening on server socket (%s): %s", addr2str(sa),
                strerror(errno));
        return -1;
    }

    return fd;
}
Beispiel #17
0
/*
 * Funzione prova a connetersi ai superpeer indicati nella lista passata come parametro.
 * Ritorna 0 in caso di successo e -1 se si è verificato un errore o se non è riuscita
 * a connettersi a nessun superpeer della lista.
 */
int join_overlay(const struct sockaddr_in *sp_addr_list, int list_len) {
	int i, ok = 1;
	int sock_tmp;
	int addr_check = 0;
	int j, nread;
	struct sockaddr_in *addr_list;
	struct packet recv_pck;


	if (list_len > max_tcp_sock / 2) {
		near_str = (char *)realloc(near_str, list_len * 2 * ADDR_STR_LEN);
		memset(near_str + max_tcp_sock * ADDR_STR_LEN, 0, (list_len * 2 - max_tcp_sock) * ADDR_STR_LEN);
		max_tcp_sock = list_len * 2;
	}

	for (i = 0; i < list_len; i ++) {
		if (get_near_by_addr(&sp_addr_list[i]) != NULL) {
			continue;
		}
		if (ok) {
			if ((sock_tmp = tcp_socket()) < 0) {
				perror("join_overlay error - can't initialize tcp socket");
				return -1;
			}
			//printf("SOCKET: %d\n", sock_tmp);
//			printf("LISTLEN: %d\n", list_len);
		}
		printf("join_overlay - addr: %s:%d\n", inet_ntoa(sp_addr_list[i].sin_addr), ntohs(sp_addr_list[i].sin_port));
		if (tcp_connect(sock_tmp, &sp_addr_list[i]) < 0) {
			perror("join_overlay error - can't connect to superpeer");
			ok = 0;
			continue; //provo il prossimo indirizzo
		} else {
			printf("Connected with superpeer %s:%d\n", inet_ntoa(sp_addr_list[i].sin_addr), ntohs(sp_addr_list[i].sin_port));
			if (addr_check == 0) {
				get_local_addr(sock_tmp, &myaddr);
				addr_check = 1;
			}
			ok = 1;

			if ((nread = recv_packet_tcp(sock_tmp, &recv_pck)) < 0) {
				perror("join_overlay error - recv_packet_tcp failed\n");
				return -1;
			} else if (nread == 0) {
				printf("join_overlay - connection closed by superpeer\n");
				if (close(sock_tmp) < 0) {
					perror("join_overlay error - close failed");
					return -1;
				}
				continue;	
			}

			if (!strncmp(recv_pck.cmd, CMD_ACK, CMD_STR_LEN)) {
				if (write(sock_tmp, (char *)&conf.udp_port, sizeof(conf.udp_port)) < 0) {
					perror("join_overlay error - write failed\n");
					return -1;
				}
				fd_add(sock_tmp);
				if (insert_near(sock_tmp, &sp_addr_list[i]) < 0) {
					fprintf(stderr, "join_overlay error - insert_near failed\n");
					return -1;
				}

				addr2str(near_str + nsock * 6, sp_addr_list[i].sin_addr.s_addr, sp_addr_list[i].sin_port);	
				addr_list = str_to_addr(near_str, max_tcp_sock);
				for(j = 0; j < max_tcp_sock; j ++){
					printf("join_overlay - near %s:%d\n", inet_ntoa(addr_list[j].sin_addr), ntohs(addr_list[j].sin_port));
				}

				nsock ++;

			} else if (!strncmp(recv_pck.cmd, CMD_ERR, CMD_STR_LEN)) {
				printf("RICEVUTO ERR\n");
				printf("join_overlay - connection closed by superpeer\n");
				if (close(sock_tmp) < 0) {
					perror("join_overlay error - close failed");
					return -1;
				}
				continue;	
			} else {
				fprintf(stderr, "join_overlay error - packet not expected\n");
				if (close(sock_tmp) < 0) {
					perror("join_overlay error - close failed");
					return -1;
				}
				continue;	
			}
		}
	}


	if (!ok) {
		close(sock_tmp);
	}

	if (nsock != list_len) {
		printf("join_overlay error - can't connect to all superpeer in the list\n");
		return 1;
	} 

	return 0;
	
}
int
relay6_script(
	char *scriptpath,
	struct sockaddr_in6 *client,
	struct dhcp6 *dh6,
	int len
)
{
	struct dhcp6_optinfo optinfo;
	struct dhcp6opt *optend;
	int i, j, iapds, ianas, envc, elen, ret = 0;
	char **envp, *s, *t;
	struct dhcp6_listval *v;
	pid_t pid, wpid;

	/* if a script is not specified, do nothing */
	if (scriptpath == NULL || strlen(scriptpath) == 0)
		return -1;

	/* only replies are interesting */
	if (dh6->dh6_msgtype != DH6_REPLY) {
		if (dh6->dh6_msgtype != DH6_ADVERTISE) {
			dprintf(LOG_INFO, FNAME, "forward msg#%d to client?",
			    dh6->dh6_msgtype);
			return -1;
		}
		return 0;
	}

	/* parse options */
	optend = (struct dhcp6opt *)((caddr_t) dh6 + len);
	dhcp6_init_options(&optinfo);
	if (dhcp6_get_options((struct dhcp6opt *)(dh6 + 1), optend,
	    &optinfo) < 0) {
		dprintf(LOG_INFO, FNAME, "failed to parse options");
		return -1;
	}

	/* initialize counters */
	iapds = 0;
	ianas = 0;
	envc = 2;     /* we at least include the address and the terminator */

	/* count the number of variables */
	for (v = TAILQ_FIRST(&optinfo.iapd_list); v; v = TAILQ_NEXT(v, link))
		iapds++;
	envc += iapds;
	for (v = TAILQ_FIRST(&optinfo.iana_list); v; v = TAILQ_NEXT(v, link))
		ianas++;
	envc += ianas;

	/* allocate an environments array */
	if ((envp = malloc(sizeof (char *) * envc)) == NULL) {
		dprintf(LOG_NOTICE, FNAME,
		    "failed to allocate environment buffer");
		dhcp6_clear_options(&optinfo);
		return -1;
	}
	memset(envp, 0, sizeof (char *) * envc);

	/*
	 * Copy the parameters as environment variables
	 */
	i = 0;
	/* address */
	t = addr2str((struct sockaddr *) client);
	if (t == NULL) {
		dprintf(LOG_NOTICE, FNAME,
		    "failed to get address of client");
		ret = -1;
		goto clean;
	}
	elen = sizeof (client_str) + 1 + strlen(t) + 1;
	if ((s = envp[i++] = malloc(elen)) == NULL) {
		dprintf(LOG_NOTICE, FNAME,
		    "failed to allocate string for client");
		ret = -1;
		goto clean;
	}
	memset(s, 0, elen);
	snprintf(s, elen, "%s=%s", client_str, t);
	/* IAs */
	j = 0;
	for (v = TAILQ_FIRST(&optinfo.iapd_list); v;
	    v = TAILQ_NEXT(v, link)) {
		if ((s = envp[i++] = iapd2str(j++, v)) == NULL) {
			ret = -1;
			goto clean;
		}
	}
	j = 0;
	for (v = TAILQ_FIRST(&optinfo.iana_list); v;
	    v = TAILQ_NEXT(v, link)) {
		if ((s = envp[i++] = iana2str(j++, v)) == NULL) {
			ret = -1;
			goto clean;
		}
	}

	/* launch the script */
	pid = fork();
	if (pid < 0) {
		dprintf(LOG_ERR, FNAME, "failed to fork: %s", strerror(errno));
		ret = -1;
		goto clean;
	} else if (pid) {
		int wstatus;

		do {
			wpid = wait(&wstatus);
		} while (wpid != pid && wpid > 0);

		if (wpid < 0)
			dprintf(LOG_ERR, FNAME, "wait: %s", strerror(errno));
		else {
			dprintf(LOG_DEBUG, FNAME,
			    "script \"%s\" terminated", scriptpath);
		}
	} else {
		char *argv[2];
		int fd;

		argv[0] = scriptpath;
		argv[1] = NULL;

		if (safefile(scriptpath)) {
			dprintf(LOG_ERR, FNAME,
			    "script \"%s\" cannot be executed safely",
			    scriptpath);
			exit(1);
		}

		if (foreground == 0 &&
		    (fd = open("/dev/null", O_RDWR)) != -1) {
			dup2(fd, STDIN_FILENO);
			dup2(fd, STDOUT_FILENO);
			dup2(fd, STDERR_FILENO);
			if (fd > STDERR_FILENO)
				close(fd);
		}

		execve(scriptpath, argv, envp);

		dprintf(LOG_ERR, FNAME, "child: exec failed: %s",
		    strerror(errno));
		exit(0);
	}

  clean:
	for (i = 0; i < envc; i++)
		free(envp[i]);
	free(envp);
	dhcp6_clear_options(&optinfo);

	return ret;
}
Beispiel #19
0
void
main(int argc, char *argv[])
{
	uchar buf[8*1024], *p;
	char addr[128], dir[40], ldir[40], *s;
	int cmd, fd, cfd, n;
	NetConnInfo *nc;

	fmtinstall('I', eipfmt);

	setnetmtpt(inside, sizeof(inside), 0);
	setnetmtpt(outside, sizeof(outside), 0);
	ARGBEGIN {
	case 'x':
		setnetmtpt(inside, sizeof(inside), ARGF());
		break;
	case 'o':
		setnetmtpt(outside, sizeof(outside), ARGF());
		break;
	} ARGEND;

	/* ver+cmd or ver+nmethod */
	if(readn(0, buf, 2) != 2)
		return;
	socksver = buf[0];
	if(socksver < 4)
		return;
	if(socksver > 5)
		socksver = 5;

	if(socksver == 4){
		/* port+ip4 */
		if(readn(0, buf+2, 2+4) != 2+4)
			return;
		/* +user\0 */
		for(p = buf+2+2+4;; p++){
			if(p >= buf+sizeof(buf))
				return;
			if(read(0, p, 1) != 1)
				return;
			if(*p == 0)
				break;
		}
		/* socks 4a dom hack */
		if((buf[4] | buf[5] | buf[6]) == 0 && buf[7]){
			/* +dom\0 */
			for(++p;; p++){
				if(p >= buf+sizeof(buf))
					return;
				if(read(0, p, 1) != 1)
					return;
				if(*p == 0)
					break;
			}
		}
	} else {
		/* nmethod */
		if((n = buf[1]) > 0)
			if(readn(0, buf+2, n) != n)
				return;

		/* ver+method */
		buf[0] = socksver;
		buf[1] = 0x00;	/* no authentication required */
		if(write(1, buf, 2) != 2)
			return;

		/* ver+cmd+res+atyp */
		if(readn(0, buf, 4) != 4)
			return;
		switch(buf[3]){
		default:
			return;
		case 0x01:	/* +ipv4 */
			if(readn(0, buf+4, 4+2) != 4+2)
				return;
			break;
		case 0x03:	/* +len+dom[len] */
			if(readn(0, buf+4, 1) != 1)
				return;
			if((n = buf[4]) == 0)
				return;
			if(readn(0, buf+5, n+2) != n+2)
				return;
			break;
		case 0x04:	/* +ipv6 */
			if(readn(0, buf+4, 16+2) != 16+2)
				return;
			break;
		}
	}

	dir[0] = 0;
	fd = cfd = -1;
	cmd = buf[1];
	switch(cmd){
	case 0x01:	/* CONNECT */
		snprint(addr, sizeof(addr), "%s/tcp", outside);
		if((s = addr2str(addr, buf)) == nil)
			break;
		alarm(30000);
		fd = dial(s, 0, dir, &cfd);
		alarm(0);
		break;
	case 0x02:	/* BIND */
		if(myipaddr(buf, outside) < 0)
			break;
		snprint(addr, sizeof(addr), "%s/tcp!%I!0", outside, buf);
		fd = announce(addr, dir);
		break;
	case 0x03:	/* UDP */
		if(myipaddr(buf, inside) < 0)
			break;
		snprint(addr, sizeof(addr), "%s/udp!%I!0", inside, buf);
		fd = announce(addr, dir);
		break;
	}

Reply:
	/* reply */
	buf[1] = sockerr(fd < 0);			/* status */
	if(socksver == 4){
		buf[0] = 0x00;				/* vc */
		if(fd < 0){
			memset(buf+2, 0, 2+4);
			write(1, buf, 2+2+4);
			return;
		}
	} else {
		buf[0] = socksver;			/* ver */
		buf[2] = 0x00;				/* res */
		if(fd < 0){
			buf[3] = 0x01;			/* atyp */
			memset(buf+4, 0, 4+2);
			write(1, buf, 4+4+2);
			return;
		}
	}
	if((nc = getnetconninfo(dir, cfd)) == nil)
		return;
	if((n = str2addr((cmd & 0x100) ? nc->raddr : nc->laddr, buf)) <= 0)
		return;
	if(write(1, buf, n) != n)
		return;

	switch(cmd){
	default:
		return;
	case 0x01:	/* CONNECT */
		break;
	case 0x02:	/* BIND */
		cfd = listen(dir, ldir);
		close(fd);
		fd = -1;
		if(cfd >= 0){
			strcpy(dir, ldir);
			fd = accept(cfd, dir);
		}
		cmd |= 0x100;
		goto Reply;
	case 0x102:
		break;		
	case 0x03:	/* UDP */
		if(udprelay(fd, dir) == 0)
			while(read(0, buf, sizeof(buf)) > 0)
				;
		goto Hangup;
	}
	
	/* relay data */
	switch(rfork(RFMEM|RFPROC|RFFDG|RFNOWAIT)){
	case -1:
		return;
	case 0:
		dup(fd, 0);
		break;
	default:
		dup(fd, 1);
	}
	while((n = read(0, buf, sizeof(buf))) > 0)
		if(write(1, buf, n) != n)
			break;
Hangup:
	if(cfd >= 0)
		hangup(cfd);
	postnote(PNGROUP, getpid(), "kill");
}
Beispiel #20
0
static void rtnl_print_route(struct nlmsghdr *hdr)
{
	struct rtmsg *rtm = NLMSG_DATA(hdr);
	uint32_t attrs_len = RTM_PAYLOAD(hdr);
	struct rtattr *attr = RTM_RTA(rtm);
	struct rta_cacheinfo *ci;
	int hz = get_user_hz();
	char addr_str[256];
	char flags[256];

	if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*rtm)))
		return;

	tprintf(" [ Route Family %d (%s%s%s)", rtm->rtm_family,
			colorize_start(bold),
			addr_family2str(rtm->rtm_family),
			colorize_end());
	tprintf(", Dst Len %d", rtm->rtm_dst_len);
	tprintf(", Src Len %d", rtm->rtm_src_len);
	tprintf(", ToS %d", rtm->rtm_tos);
	tprintf(", Table %d (%s%s%s)", rtm->rtm_table,
			colorize_start(bold),
			route_table2str(rtm->rtm_table),
			colorize_end());
	tprintf(", Proto %d (%s%s%s)", rtm->rtm_protocol,
			colorize_start(bold),
			route_proto2str(rtm->rtm_protocol),
			colorize_end());
	tprintf(", Scope %d (%s%s%s)", rtm->rtm_scope,
			colorize_start(bold),
			scope2str(rtm->rtm_scope),
			colorize_end());
	tprintf(", Type %d (%s%s%s)", rtm->rtm_type,
			colorize_start(bold),
			route_type2str(rtm->rtm_type),
			colorize_end());
	tprintf(", Flags 0x%x (%s%s%s) ]\n", rtm->rtm_flags,
			colorize_start(bold),
			flags2str(route_flags, rtm->rtm_flags, flags,
				sizeof(flags)),
			colorize_end());

	for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) {
		switch (attr->rta_type) {
		case RTA_DST:
			rta_fmt(attr, "Dst %s", addr2str(rtm->rtm_family,
				RTA_DATA(attr), addr_str, sizeof(addr_str)));
			break;
		case RTA_SRC:
			rta_fmt(attr, "Src %s", addr2str(rtm->rtm_family,
				RTA_DATA(attr), addr_str, sizeof(addr_str)));
			break;
		case RTA_IIF:
			rta_fmt(attr, "Iif %d", RTA_INT(attr));
			break;
		case RTA_OIF:
			rta_fmt(attr, "Oif %d", RTA_INT(attr));
			break;
		case RTA_GATEWAY:
			rta_fmt(attr, "Gateway %s", addr2str(rtm->rtm_family,
				RTA_DATA(attr), addr_str, sizeof(addr_str)));
			break;
		case RTA_PRIORITY:
			rta_fmt(attr, "Priority %u", RTA_UINT32(attr));
			break;
		case RTA_PREFSRC:
			rta_fmt(attr, "Pref Src %s", addr2str(rtm->rtm_family,
				RTA_DATA(attr), addr_str, sizeof(addr_str)));
			break;
		case RTA_MARK:
			rta_fmt(attr, "Mark 0x%x", RTA_UINT(attr));
			break;
		case RTA_FLOW:
			rta_fmt(attr, "Flow 0x%x", RTA_UINT(attr));
			break;
		case RTA_TABLE:
			rta_fmt(attr, "Table %d (%s%s%s)", RTA_UINT32(attr),
				colorize_start(bold),
				route_table2str(RTA_UINT32(attr)),
				colorize_end());
			break;
		case RTA_CACHEINFO:
			ci = RTA_DATA(attr);
			tprintf("\tA: Cache (");
			tprintf("expires(%ds)", ci->rta_expires / hz);
			tprintf(", error(%d)", ci->rta_error);
			tprintf(", users(%d)", ci->rta_clntref);
			tprintf(", used(%d)", ci->rta_used);
			tprintf(", last use(%ds)", ci->rta_lastuse / hz);
			tprintf(", id(%d)", ci->rta_id);
			tprintf(", ts(%d)", ci->rta_ts);
			tprintf(", ts age(%ds))", ci->rta_tsage);
			tprintf(", Len %d\n", RTA_LEN(attr));
			break;
		default:
			rta_fmt(attr, "0x%x", attr->rta_type);
			break;
		}
	}
}
Beispiel #21
0
static void rtnl_print_neigh(struct nlmsghdr *hdr)
{
	struct ndmsg *ndm = NLMSG_DATA(hdr);
	uint32_t attrs_len = NDA_PAYLOAD(hdr);
	struct rtattr *attr = NDA_RTA(ndm);
	struct nda_cacheinfo *ci;
	int hz = get_user_hz();
	char addr_str[256];
	char hw_addr[30];
	char states[256];
	char flags[256];

	if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*ndm)))
		return;

	tprintf(" [ Neigh Family %d (%s%s%s)", ndm->ndm_family,
			colorize_start(bold),
			addr_family2str(ndm->ndm_family),
			colorize_end());
	tprintf(", Link Index %d", ndm->ndm_ifindex);
	tprintf(", State %d (%s%s%s)", ndm->ndm_state,
			colorize_start(bold),
			flags2str(neigh_states, ndm->ndm_state, states,
				sizeof(states)),
			colorize_end());
	tprintf(", Flags %d (%s%s%s)", ndm->ndm_flags,
			colorize_start(bold),
			flags2str(neigh_flags, ndm->ndm_flags, flags,
				sizeof(flags)),
			colorize_end());
	tprintf(", Type %d (%s%s%s)", ndm->ndm_type,
			colorize_start(bold),
			route_type2str(ndm->ndm_type),
			colorize_end());
	tprintf(" ]\n");

	for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) {
		switch (attr->rta_type) {
		case NDA_DST:
			rta_fmt(attr, "Address %s", addr2str(ndm->ndm_family,
						RTA_DATA(attr), addr_str,
						sizeof(addr_str)));
			break;
		case NDA_LLADDR:
			rta_fmt(attr, "HW Address %s",
					device_addr2str(RTA_DATA(attr),
						RTA_LEN(attr), 0, hw_addr,
						sizeof(hw_addr)));
			break;
		case NDA_PROBES:
			rta_fmt(attr, "Probes %d", RTA_UINT32(attr));
			break;
		case NDA_CACHEINFO:
			ci = RTA_DATA(attr);
			tprintf("\tA: Cache (");
			tprintf("confirmed(%ds)", ci->ndm_confirmed / hz);
			tprintf(", used(%ds)", ci->ndm_used / hz);
			tprintf(", updated(%ds)", ci->ndm_updated / hz);
			tprintf(", refcnt(%d))", ci->ndm_refcnt);
			tprintf(", Len %d\n", RTA_LEN(attr));
			break;
		default:
			rta_fmt(attr, "0x%x", attr->rta_type);
			break;
		}
	}
}
Beispiel #22
0
	/// Converts the contained MAC address to a string via the static addr2str().
	std::string addr2str() const { return addr2str(_address); }
Beispiel #23
0
static void rtnl_print_ifaddr(struct nlmsghdr *hdr)
{
	struct ifaddrmsg *ifa = NLMSG_DATA(hdr);
	uint32_t attrs_len = IFA_PAYLOAD(hdr);
	struct rtattr *attr = IFA_RTA(ifa);
	struct ifa_cacheinfo *ci;
	char addr_str[256];
	char flags[256];

	if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*ifa)))
		return;

	tprintf(" [ Address Family %d (%s%s%s)", ifa->ifa_family,
			colorize_start(bold),
			addr_family2str(ifa->ifa_family),
			colorize_end());
	tprintf(", Prefix Len %d", ifa->ifa_prefixlen);
	tprintf(", Flags %d (%s%s%s)", ifa->ifa_flags,
			colorize_start(bold),
			rtnl_addr_flags2str(ifa->ifa_flags, flags,
				sizeof(flags)),
			colorize_end());
	tprintf(", Scope %d (%s%s%s)", ifa->ifa_scope,
			colorize_start(bold),
			scope2str(ifa->ifa_scope),
			colorize_end());
	tprintf(", Link Index %d ]\n", ifa->ifa_index);

	for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) {
		switch (attr->rta_type) {
		case IFA_LOCAL:
			rta_fmt(attr, "Local %s", addr2str(ifa->ifa_family,
				RTA_DATA(attr), addr_str, sizeof(addr_str)));
			break;
		case IFA_ADDRESS:
			rta_fmt(attr, "Address %s", addr2str(ifa->ifa_family,
				RTA_DATA(attr), addr_str, sizeof(addr_str)));
			break;
		case IFA_BROADCAST:
			rta_fmt(attr, "Broadcast %s",
					addr2str(ifa->ifa_family,
						RTA_DATA(attr), addr_str,
						sizeof(addr_str)));
			break;
		case IFA_MULTICAST:
			rta_fmt(attr, "Multicast %s",
					addr2str(ifa->ifa_family,
						RTA_DATA(attr), addr_str,
						sizeof(addr_str)));
			break;
		case IFA_ANYCAST:
			rta_fmt(attr, "Anycast %s", addr2str(ifa->ifa_family,
				RTA_DATA(attr), addr_str, sizeof(addr_str)));
			break;
#ifdef IFA_FLAGS
		case IFA_FLAGS:
			rta_fmt(attr, "Flags %d (%s%s%s)", RTA_INT(attr),
				colorize_start(bold),
				rtnl_addr_flags2str(RTA_INT(attr),
					flags, sizeof(flags)),
				colorize_end());
			break;
#endif
		case IFA_LABEL:
			rta_fmt(attr, "Label %s", RTA_STR(attr));
			break;
		case IFA_CACHEINFO:
			ci = RTA_DATA(attr);
			tprintf("\tA: Cache (");

			if (ci->ifa_valid == INFINITY)
				tprintf("valid lft(forever)");
			else
				tprintf("valid lft(%us)", ci->ifa_valid);

			if (ci->ifa_prefered == INFINITY)
				tprintf(", prefrd lft(forever)");
			else
				tprintf(", prefrd lft(%us)", ci->ifa_prefered);

			tprintf(", created on(%.2fs)", (double)ci->cstamp / 100);
			tprintf(", updated on(%.2fs))", (double)ci->cstamp / 100);
			tprintf(", Len %d\n", RTA_LEN(attr));
			break;
		default:
			rta_fmt(attr, "0x%x", attr->rta_type);
			break;
		}
	}
}
Beispiel #24
0
int handle_prepare(connection *con, uint32_t size, void* data) {
    prepare_msg* msg = (prepare_msg*)data;
    char ipstr[32];

    int ret = 0;
    acceptor_record* rec;

    rec = &acc.instance_cache[GET_ACC_INDEX(msg->iid)];

    // Handle a new instance,
    // possibly get rid of an old instance
    if (msg->iid > rec->iid) {
        rec->iid = msg->iid;
        rec->ballot = msg->ballot;
        rec->value_ballot = -1;
        if (rec->value != NULL) {
            free(rec->value);
        }
        rec->value = NULL;

        L_DEBUG("Promising for instance %d with ballot %d, never seen before\n", msg->iid, msg->ballot);
        stablestorage_save_prepare(msg ,rec);
        //return add_promise_to_send_buffer(rec);
        return send_promise_message(addr2str(ipstr, con->remoteaddr), con->remoteport, rec);
    }

    // Handle a previously written instance
    if (msg->iid == rec->iid) {
        if (msg->ballot <= rec->ballot) {
            L_DEBUG("Ignoring prepare for instance %d with ballot %d, already promised to %d\n", msg->iid, msg->ballot, rec->ballot);
            return 1;
        }
        //Answer if ballot is greater then last one
        L_DEBUG("Promising for instance %d with ballot %d, previously promised to %d\n", msg->iid, msg->ballot, rec->ballot);
        rec->ballot = msg->ballot;
        stablestorage_save_prepare(msg ,rec);
        //return add_promise_to_send_buffer(rec);
        return send_promise_message(addr2str(ipstr, con->remoteaddr), con->remoteport, rec);
    }

    //Record was overwritten in memory, retrieve from disk
    if (msg->iid < rec->iid) {
        rec = stablestorage_get_record(msg->iid);
        if(rec == NULL) {
            //No record on disk
            rec = malloc(sizeof(acceptor_record));
            rec->iid           = msg->iid;
            rec->ballot        = -1;
            rec->value_ballot  = -1;
            rec->value = NULL;
        }

        if(msg->ballot > rec->ballot) {
            rec->ballot = msg->ballot;
            stablestorage_save_prepare(msg ,rec);
            //ret = add_promise_to_send_buffer(rec);
            ret = send_promise_message(addr2str(ipstr, con->remoteaddr), con->remoteport, rec);

        } else {
            L_DEBUG("Ignoring prepare for instance %d with ballot %d, already promised to %d [info from disk]\n", msg->iid, msg->ballot, rec->ballot);
            ret = 0;
        }
    }

    if(rec != NULL) {
        if(rec->value != NULL) {
            free(rec->value);
        }
        free(rec);
    }

    return ret;
}
Beispiel #25
0
static void
handle_new_connection(int newfd, int epfd)
{
    struct epoll_event ev;
    struct client_data *client;
    struct sockaddr_storage addr;
    socklen_t addrlen = sizeof (addr);
    char authbuf[AUTHBUFSIZE];
    int pos, is_reg, reconnect_id, authlen, userid;
    static int connection_id = 1;

    if (fd_to_client_max > newfd &&
        fd_to_client[newfd] == &new_connection_dummy) {
        epoll_ctl(epfd, EPOLL_CTL_DEL, newfd, &ev);
        fd_to_client[newfd] = NULL;
    }

    /* it should be possible to read immediately due to the "defer" sockopt */
    authlen = read(newfd, authbuf, AUTHBUFSIZE - 1);
    if (authlen <= 0) {
        close(newfd);
        return;
    }

    getpeername(newfd, (struct sockaddr *)&addr, &addrlen);
    log_msg("New connection from %s.", addr2str(&addr));

    authbuf[authlen] = '\0';    /* make it safe to use as a string */

    /* did we receive too much data? */
    if (authlen >= AUTH_MAXLEN) {
        log_msg("Auth buffer overrun attempt from %s? Peer disconnected.",
                addr2str(&addr));
        close(newfd);
        return;
    }

    /* check the end of the received auth data: a JSON object always ends with
       '}' */
    pos = authlen - 1;
    while (pos > 0 && isspace(authbuf[pos]))
        pos--;

    if (authbuf[pos] != '}') {  /* not the end of JSON auth data */
        log_msg("authentication for %s failed due to incomplete JSON",
                addr2str(&addr));
        return;
    }

    /* 
     * ready to authenticate the user here
     */
    userid = auth_user(authbuf, addr2str(&addr), &is_reg, &reconnect_id);
    if (userid <= 0) {
        if (!userid)
            auth_send_result(newfd, AUTH_FAILED_UNKNOWN_USER, is_reg, 0);
        else
            auth_send_result(newfd, AUTH_FAILED_BAD_PASSWORD, is_reg, 0);
        log_msg("authentication failed for %s", addr2str(&addr));
        close(newfd);
        return;
    }

    /* user ok, we'll keep this socket */
    ev.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET;
    ev.data.ptr = NULL;
    ev.data.fd = newfd;
    if (epoll_ctl(epfd, EPOLL_CTL_ADD, newfd, &ev) == -1) {
        log_msg("Error in epoll_ctl for %s: %s", addr2str(&addr),
                strerror(errno));
        close(newfd);
        return;
    }

    /* is the client re-establishing a connection to an existing, disconnected
       game? */
    for (client = disconnected_list_head.next; client; client = client->next)
        if (client->userid == userid &&
            (!reconnect_id || reconnect_id == client->connid))
            break;
    if (reconnect_id && !client) {
        /* now search through the active connections. The client might have a
           new IP address, which would leave the socket open and seemingly
           valid. */
        for (client = connected_list_head.next; client; client = client->next)
            if (client->userid == userid && reconnect_id == client->connid)
                break;
    }

    if (client) {
        /* there is a running, disconnected game process for this user */
        auth_send_result(newfd, AUTH_SUCCESS_RECONNECT, is_reg, client->connid);
        client->sock = newfd;
        map_fd_to_client(client->sock, client);
        client->state = CLIENT_CONNECTED;
        unlink_client_data(client);
        link_client_data(client, &connected_list_head);
        write(client->pipe_out, "\033", 1);     /* signal to reset the read
                                                   buffer */

        log_msg("Connection to game at pid %d reestablished for user %d",
                client->pid, client->userid);
        return;
    } else {
        client = alloc_client_data(&connected_list_head);
        client->state = CLIENT_CONNECTED;
        client->sock = newfd;
        map_fd_to_client(newfd, client);
        client->connid = connection_id++;
        client->userid = userid;
        /* there is no process yet */
        if (fork_client(client, epfd))
            auth_send_result(newfd, AUTH_SUCCESS_NEW, is_reg, client->connid);
        /* else: client communication is shutdown if fork_client errors out */
    }

    log_msg("There are now %d clients on the server", client_count);
}
Beispiel #26
0
static int listen_to(selene_conf_t *conf, const char *host, int port,
                     FILE *fp) {
  fd_set readers;
  int rv = 0;
  server_t server;
  char buf[8096];
  char port_str[16];
  char *p = NULL;
  struct addrinfo hints, *res, *res0;
  selene_error_t *err = NULL;
  char ip_buf[INET6_ADDRSTRLEN];
  char *ip_str = NULL;

  memset(&server, 0, sizeof(server));

  snprintf(port_str, sizeof(port_str), "%i", port);
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_INET;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
  rv = getaddrinfo(host, port_str, &hints, &res0);
  if (rv != 0) {
    fprintf(stderr, "TCP getaddrinfo(%s:%d) failed: (%d) %s\n", host, port, rv,
            gai_strerror(rv));
    exit(EXIT_FAILURE);
  }

  server.sock = -1;
  for (res = res0; res; res = res->ai_next) {

    server.listen_sock =
        socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    if (server.listen_sock < 0) {
      continue;
    }

    ip_str = addr2str(res->ai_addr, &ip_buf[0], sizeof(ip_buf));

    fprintf(stderr, "TCP bind(%s:%d)\n", ip_str, port);

    rv = bind(server.listen_sock, res->ai_addr, res->ai_addrlen);
    if (rv != 0) {
      close(server.listen_sock);
      server.listen_sock = -1;
      continue;
    }

    rv = listen(server.listen_sock, 10);
    if (rv != 0) {
      close(server.listen_sock);
      server.listen_sock = -1;
      continue;
    }

    break;
  }

  freeaddrinfo(res0);

  if (server.listen_sock == -1) {
    fprintf(stderr, "TCP bind(%s:%d) failed\n", host, port);
    exit(EXIT_FAILURE);
  }

  server.sock = -1;

  while (server.write_err == 0) {
    FD_ZERO(&readers);

    FD_SET(server.listen_sock, &readers);
    if (server.sock != -1) {
      FD_SET(server.sock, &readers);
    }
    FD_SET(fileno(fp), &readers);

    rv = select(FD_SETSIZE, &readers, NULL, NULL, NULL);

    if (rv > 0) {
      if (FD_ISSET(fileno(fp), &readers)) {
        p = fgets(buf, sizeof(buf), fp);

        if (p == NULL) {
          break;
        }

        if (server.sock != -1) {
          SERR(selene_io_in_clear_bytes(server.s, p, strlen(p)));
        }
      } else if (FD_ISSET(server.listen_sock, &readers)) {
        /* TODO: multiple client support */
        if (server.sock == -1) {
          server.sock = accept(server.listen_sock, NULL, 0);

          err = selene_server_create(conf, &server.s);
          if (err != SELENE_SUCCESS) {
            fprintf(stderr,
                    "Failed to create client instance: (%d) %s [%s:%d]\n",
                    err->err, err->msg, err->file, err->line);
            exit(EXIT_FAILURE);
          }

          selene_subscribe(server.s, SELENE_EVENT_LOG_MSG, have_logline, NULL);

          SERR(selene_subscribe(server.s, SELENE_EVENT_IO_OUT_ENC, want_pull,
                                &server));

          SERR(selene_subscribe(server.s, SELENE_EVENT_IO_OUT_CLEAR,
                                have_cleartext, &server));

          SERR(selene_start(server.s));
        }
      } else if (server.sock != -1 && FD_ISSET(server.sock, &readers)) {
        read_from_sock(&server);
      }
    }
  }

  if (server.write_err != 0) {
    /* TODO: client ip */
    fprintf(stderr, "TCP write from %s:%d failed: (%d) %s\n", host, port,
            server.write_err, strerror(server.write_err));
    exit(EXIT_FAILURE);
  }

  if (server.read_err != 0) {
    /* TODO: just disconnect client, keep listening */
    fprintf(stderr, "TCP read on %s:%d failed: (%d) %s\n", host, port,
            server.read_err, strerror(server.read_err));
    exit(EXIT_FAILURE);
  }

  if (server.s) {
    selene_destroy(server.s);
    server.s = NULL;
  }

  return 0;
}
Beispiel #27
0
void ax25_display_addr(Stream* out, addr_t* a)
{
    char buf[10];
    addr2str(buf, a);
    putstr(out, buf);
}
Beispiel #28
0
/**
 * Main SLA-NG 'probed' state machine, handling all client/server stuff
 *
 * The main loop, this is where the magic happens. One UDP (ping/pong)
 * and many TCP sockets (timestamp) is used, and those were created by
 * the function bind_or_die(). SLA-NG probed can operate in client and
 * server mode simultaneously. Client mode probes, sending PINGs, have
 * one forked TCP process each, connecting to the server, in order to
 * receive timestamps reliably. The server mode responder accepts TCP
 * connections, but doesn't fork. It simply keeps the TCP file
 * descriptor as long as the client is alive, sending timestamp packets
 * over it. We use server_find_peer_fd() to map the address of incoming
 * UDP pongs to a TCP timestamp client socket.
 *
 * CLIENT MODE                                                     \n
 *  loop: wait for time to send > send ping > save tstamp          \n
 *  loop: wait for pong > save tstamp                              \n
 *  loop: wait for pipe tstamp > save tstamp                       \n
 *  fork: connect > wait for TCP tstamp > write to pipe > wait...  \n
 *
 * SERVER MODE                                                     \n
 *  loop: wait for ping > send pong > find fd > send TCP tstamp    \n
 *  loop: wait for TCP connect > add to fd set > remove dead fds   \n
 *
 * \param[in] s_udp   Listening UDP socket to use for PING/PONG
 * \param[in] s_tcp   Listening TCP socket for client accept and TSTAMP
 * \param[in] port    client_msess_reconf's getaddrinfo needs the port
 * \param[in] cfgpath client_msess_reconf needs XML config
 * \bug       The 'first', not 'correct' TCP client socket will be used
 */
void loop_or_die(int s_udp, int s_tcp, char *port, char *cfgpath) {
	struct server_peer *p;
	char addrstr[INET6_ADDRSTRLEN];
	char byte;
	struct sockaddr_in6 addr_tmp;
	pkt_t pkt;
	data_t *rx, tx;
	ts_t ts, last_stats, now, tmp_ts;
	fd_set fs_tmp;
	int i, fd, fd_client_low, sends = 0, fd_max = 0;
	fd_set fs;
	socklen_t slen;
	int fd_client_pipe[2];
	int fd_send_pipe[2];
	int ok = 1;

	LIST_INIT(&peers_head);
	/* IPC for children-to-parent (TCP client to UDP state machine) */
	if (pipe(fd_client_pipe) < 0) {
		syslog(LOG_ERR, "pipe: %s", strerror(errno));
		exit(EXIT_FAILURE);
	}

	if (pipe(fd_send_pipe) < 0) {
		syslog(LOG_ERR, "pipe: %s", strerror(errno));
		exit(EXIT_FAILURE);
	}

	if (fcntl(fd_send_pipe[1], F_SETFL, O_NONBLOCK) < 0) {
		syslog(LOG_ERR, "fcntl: %s; fd_send_pipe[1]", strerror(errno));
		exit(EXIT_FAILURE);
	}

	if (fcntl(fd_send_pipe[0], F_SETFL, O_NONBLOCK) < 0) {
		syslog(LOG_ERR, "fcntl: %s; fd_send_pipe[0]", strerror(errno));
		exit(EXIT_FAILURE);
	}

	/* set last stats timer */
	(void)clock_gettime(CLOCK_REALTIME, &last_stats);


	/* Transmit timer */
	client_send_fork(fd_send_pipe[1]);

	/* Add both pipe, UDP and TCP to the FD set, note highest FD */
	unix_fd_zero(&fs);
	unix_fd_zero(&fs_tmp);
	unix_fd_set(s_udp, &fs);
	unix_fd_set(s_tcp, &fs);
	unix_fd_set(s_tcp, &fs);
	unix_fd_set(fd_client_pipe[0], &fs);
	unix_fd_set(fd_send_pipe[0], &fs);
	fd_max = MAX(fd_max, s_udp);
	fd_max = MAX(fd_max, s_tcp);
	fd_max = MAX(fd_max, fd_client_pipe[0]);
	fd_max = MAX(fd_max, fd_client_pipe[1]);
	fd_max = MAX(fd_max, fd_send_pipe[0]);
	fd_max = MAX(fd_max, fd_send_pipe[1]);
	fd_client_low = fd_max;

	/* Let's loop those sockets! */
	while (1 == 1) {
		fs_tmp = fs;
		if (select(fd_max + 1, &fs_tmp, NULL, NULL, NULL) > 0) {
			ok = 0;
			/* CLIENT/SERVER: UDP socket, that is PING and PONG */
			if (unix_fd_isset(s_udp, &fs_tmp) == 1) {
				ok = 1;
				if (recv_w_ts(s_udp, 0, &pkt) < 0)
					ok = 0;
				rx = (data_t *)&pkt.data;
				/* SERVER: Send UDP PONG */
				if (ok == 1 && rx->type == TYPE_PING) {
					count_server_resp++;
					tx.type = TYPE_PONG;
					tx.id = rx->id;
					tx.seq = rx->seq;
					last_tx_id = rx->id;
					last_tx_seq = rx->seq;
					tx.t2 = pkt.ts;
					(void)dscp_set(s_udp, pkt.dscp);
					(void)send_w_ts(s_udp, &(pkt.addr), (char*)&tx, &ts);
					/* Send TCP timestamp */
					tx.type = TYPE_TIME;
					tx.t3 = ts;
					fd = server_find_peer_fd(&pkt.addr);
					if (fd < 0) continue;
					if (send(fd, (char*)&tx, DATALEN, 0) != DATALEN) {
						server_kill_peer(&fs, &fd_max, fd);
					}
				}
				/* CLIENT: Update results with received UDP PONG */
				if (ok == 1 && rx->type == TYPE_PONG) {
					client_res_update(&pkt.addr, rx, &pkt.ts, pkt.dscp);
				}
			}
			/* SERVER: TCP socket, accept timestamp connection */
			if (unix_fd_isset(s_tcp, &fs_tmp) == 1) {
				ok = 1;
				slen = (socklen_t)sizeof (struct sockaddr_in6);
				memset(&addr_tmp, 0, sizeof addr_tmp);
				fd = accept(s_tcp, (struct sockaddr *)&addr_tmp, &slen);
				if (fd < 0) {
					syslog(LOG_ERR, "accept: %s", strerror(errno));
					ok = 0;
				}
				if (ok == 1 && addr2str(&addr_tmp, addrstr) == 0)
					syslog(LOG_INFO, "server: %s: %d: Connected", addrstr, fd);
				else
					ok = 0;
				if (ok == 1) {
					/* Keep track of client's FD */
					unix_fd_set(fd, &fs);
					if (fd > fd_max)
						fd_max = fd;
					/* Send hello, feed me with PINGs */
					memset(&tx, 0, sizeof tx);
					tx.type = TYPE_HELO;
					if (send(fd, (char*)&tx, DATALEN, 0) != DATALEN) {
						server_kill_peer(&fs, &fd_max, fd);
					}
					p = malloc(sizeof *p);
					if (p == NULL) return;
					p->fd = fd;
					memcpy(&p->addr, &addr_tmp, sizeof p->addr);
					LIST_INSERT_HEAD(&peers_head, p, list);
				}
			}
			/* CLIENT: PIPE; timestamps from client_fork (TCP) */
			if (unix_fd_isset(fd_client_pipe[0], &fs_tmp) == 1) {
				ok = 1;
				if (read(fd_client_pipe[0], &pkt, sizeof pkt) < 0) {
					syslog(LOG_ERR, "pipe: read: %s", strerror(errno));
					ok = 0;
				}
				rx = (data_t *)&pkt.data;
				if (ok == 1 && rx->type == TYPE_HELO) {
					/* Connected to server, ready to feed it! */
					if (client_msess_gothello(&pkt.addr) != 0)
						syslog(LOG_INFO, "client: Unknown client connected");
					if (addr2str(&pkt.addr, addrstr) == 0)
						syslog(LOG_INFO, "client: %s: Connected", addrstr);
				} else if (ok == 1 && rx->type == TYPE_TIME) {
					rx = (data_t *)&pkt.data;
					client_res_update(&pkt.addr, rx, NULL, -1);
				}
			}
			/* CLIENT: PIPE; send */
			if (unix_fd_isset(fd_send_pipe[0], &fs_tmp) == 1) {

				ok = 0;

				/* Read pipe as long as we have data.
				 * If the pipe hasn't been read for a while, we might have a
				 * large number of messages here, but should only trigger
				 * transmit function once...*/
				while (read(fd_send_pipe[0], &byte, sizeof byte) > 0) {
					ok++;
				}

				/* Did we receive any message? */
				if (ok > 0) {

					/* Warn if we had more than one message queued */
					if (ok > 1) {
						syslog(LOG_ERR, "Found %d trigger messages queued",
							ok);
					}

					/* trigger client packet transmission*/
					client_msess_transmit(s_udp, sends);

					/* reload if requested */
					if (cfg.should_reload == 1) {
						cfg.should_reload = 0;
						(void)client_msess_reconf(port, cfgpath);
						client_msess_forkall(fd_client_pipe[1]);
					}

					/* clear timed out probes every now and then */
					if (sends % (TIMEOUT_INTERVAL/SEND_INTERVAL) == 0) {
						client_res_clear_timeouts();
					}

					/* log statistics */
					if (sends % 10000 == 0 &&
							cfg.op == DAEMON) {

						/* calculate time since last statistics report */
						(void)clock_gettime(CLOCK_REALTIME, &now);
						diff_ts(&tmp_ts, &now, &last_stats);
						memcpy(&last_stats, &now, sizeof last_stats);
						syslog(LOG_INFO, "stats_delay:        %d.%d",
								(int)tmp_ts.tv_sec, (int)tmp_ts.tv_nsec);

						syslog(LOG_INFO, "count_server_resp:  %d (pps*10)",
								count_server_resp);
						syslog(LOG_INFO, "count_client_sent:  %d (pps*10)",
								count_client_sent);
						syslog(LOG_INFO, "count_client_done:  %d (pps*10)",
								count_client_done);
						syslog(LOG_INFO, "count_client_find:  %d (1)",
								count_client_find);
						syslog(LOG_INFO, "count_client_fifoq: %d (0)",
								count_client_fifoq);
						syslog(LOG_INFO, "count_client_fqmax: %d (0)",
								count_client_fifoq_max);
						count_server_resp = 0;
						count_client_sent = 0;
						count_client_done = 0;
					}

					sends++;

				} else {
					syslog(LOG_ERR, "pipe: read: %s", strerror(errno));
				}

			}
			/* It's a client. They shouldn't speak, it's probably a
			 * disconnect. KILL IT. */
			if (ok == 0) {
				for (i = fd_client_low; i <= fd_max; i++) {
					if (unix_fd_isset(i, &fs_tmp) == 1) {
						server_kill_peer(&fs, &fd_max, i);
					}
				}
			}
		} else {
			/* select() timeout */
			syslog(LOG_ERR, "select: %s", strerror(errno));
		}
	}
}
Beispiel #29
0
int
main(const int argc, char **argv)
{
    int                 n_listeners, i, clnt_length, clnt;
    struct pollfd       *polls;
    LISTENER            *lstn;
    pthread_t           thr;
    pthread_attr_t      attr;
    struct sched_param  sp;
    uid_t               user_id;
    gid_t               group_id;
    FILE                *fpid;
    struct sockaddr_storage clnt_addr;
    char                tmp[MAXBUF];
#ifndef SOL_TCP
    struct protoent     *pe;
#endif

    print_log = 0;
    (void)umask(077);
    control_sock = -1;
    log_facility = -1;
    logmsg(LOG_NOTICE, "starting...");

    signal(SIGHUP, h_shut);
    signal(SIGINT, h_shut);
    signal(SIGTERM, h_term);
    signal(SIGQUIT, h_term);
    signal(SIGPIPE, SIG_IGN);

    srandom(getpid());

    /* SSL stuff */
    SSL_load_error_strings();
    SSL_library_init();
    OpenSSL_add_all_algorithms();
    l_init();
    init_thr_arg();
    CRYPTO_set_id_callback(l_id);
    CRYPTO_set_locking_callback(l_lock);
    init_timer();

    /* prepare regular expressions */
    if(regcomp(&HEADER, "^([a-z0-9!#$%&'*+.^_`|~-]+):[ \t]*(.*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
    || regcomp(&CHUNK_HEAD, "^([0-9a-f]+).*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
    || regcomp(&RESP_SKIP, "^HTTP/1.1 100.*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
    || regcomp(&RESP_IGN, "^HTTP/1.[01] (10[1-9]|1[1-9][0-9]|204|30[456]).*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
    || regcomp(&LOCATION, "(http|https)://([^/]+)(.*)", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
    || regcomp(&AUTHORIZATION, "Authorization:[ \t]*Basic[ \t]*\"?([^ \t]*)\"?[ \t]*", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
    ) {
        logmsg(LOG_ERR, "bad essential Regex - aborted");
        exit(1);
    }

#ifndef SOL_TCP
    /* for systems without the definition */
    if((pe = getprotobyname("tcp")) == NULL) {
        logmsg(LOG_ERR, "missing TCP protocol");
        exit(1);
    }
    SOL_TCP = pe->p_proto;
#endif

    /* read config */
    config_parse(argc, argv);

    if(log_facility != -1)
        openlog("pound", LOG_CONS | LOG_NDELAY, LOG_DAEMON);
    if(ctrl_name != NULL) {
        struct sockaddr_un  ctrl;

        memset(&ctrl, 0, sizeof(ctrl));
        ctrl.sun_family = AF_UNIX;
        strncpy(ctrl.sun_path, ctrl_name, sizeof(ctrl.sun_path) - 1);
        (void)unlink(ctrl.sun_path);
        if((control_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
            logmsg(LOG_ERR, "Control \"%s\" create: %s", ctrl.sun_path, strerror(errno));
            exit(1);
        }
        if(bind(control_sock, (struct sockaddr *)&ctrl, (socklen_t)sizeof(ctrl)) < 0) {
            logmsg(LOG_ERR, "Control \"%s\" bind: %s", ctrl.sun_path, strerror(errno));
            exit(1);
        }
        listen(control_sock, 512);
    }

    /* open listeners */
    for(lstn = listeners, n_listeners = 0; lstn; lstn = lstn->next, n_listeners++) {
        int opt;

        /* prepare the socket */
        if((lstn->sock = socket(lstn->addr.ai_family == AF_INET? PF_INET: PF_INET6, SOCK_STREAM, 0)) < 0) {
            addr2str(tmp, MAXBUF - 1, &lstn->addr, 0);
            logmsg(LOG_ERR, "HTTP socket %s create: %s - aborted", tmp, strerror(errno));
            exit(1);
        }
        opt = 1;
        setsockopt(lstn->sock, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(opt));
        if(bind(lstn->sock, lstn->addr.ai_addr, (socklen_t)lstn->addr.ai_addrlen) < 0) {
            addr2str(tmp, MAXBUF - 1, &lstn->addr, 0);
            logmsg(LOG_ERR, "HTTP socket bind %s: %s - aborted", tmp, strerror(errno));
            exit(1);
        }
        listen(lstn->sock, 512);
    }

    /* alloc the poll structures */
    if((polls = (struct pollfd *)calloc(n_listeners, sizeof(struct pollfd))) == NULL) {
        logmsg(LOG_ERR, "Out of memory for poll - aborted");
        exit(1);
    }
    for(lstn = listeners, i = 0; lstn; lstn = lstn->next, i++)
        polls[i].fd = lstn->sock;

    /* set uid if necessary */
    if(user) {
        struct passwd   *pw;

        if((pw = getpwnam(user)) == NULL) {
            logmsg(LOG_ERR, "no such user %s - aborted", user);
            exit(1);
        }
        user_id = pw->pw_uid;
    }

    /* set gid if necessary */
    if(group) {
        struct group    *gr;

        if((gr = getgrnam(group)) == NULL) {
            logmsg(LOG_ERR, "no such group %s - aborted", group);
            exit(1);
        }
        group_id = gr->gr_gid;
    }

    /* Turn off verbose messages (if necessary) */
    print_log = 0;

    if(daemonize) {
        /* daemonize - make ourselves a subprocess. */
        switch (fork()) {
            case 0:
                if(log_facility != -1) {
                    close(0);
                    close(1);
                    close(2);
                }
                break;
            case -1:
                logmsg(LOG_ERR, "fork: %s - aborted", strerror(errno));
                exit(1);
            default:
                exit(0);
        }
#ifdef  HAVE_SETSID
        (void) setsid();
#endif
    }

    /* record pid in file */
    if((fpid = fopen(pid_name, "wt")) != NULL) {
        fprintf(fpid, "%d\n", getpid());
        fclose(fpid);
    } else
        logmsg(LOG_NOTICE, "Create \"%s\": %s", pid_name, strerror(errno));

    /* chroot if necessary */
    if(root_jail) {
        if(chroot(root_jail)) {
            logmsg(LOG_ERR, "chroot: %s - aborted", strerror(errno));
            exit(1);
        }
        if(chdir("/")) {
            logmsg(LOG_ERR, "chroot/chdir: %s - aborted", strerror(errno));
            exit(1);
        }
    }

    if(group)
        if(setgid(group_id) || setegid(group_id)) {
            logmsg(LOG_ERR, "setgid: %s - aborted", strerror(errno));
            exit(1);
        }
    if(user)
        if(setuid(user_id) || seteuid(user_id)) {
            logmsg(LOG_ERR, "setuid: %s - aborted", strerror(errno));
            exit(1);
        }

    /* split off into monitor and working process if necessary */
    for(;;) {
#ifdef  UPER
        if((son = fork()) > 0) {
            int status;

            (void)wait(&status);
            if(WIFEXITED(status))
                logmsg(LOG_ERR, "MONITOR: worker exited normally %d, restarting...", WEXITSTATUS(status));
            else if(WIFSIGNALED(status))
                logmsg(LOG_ERR, "MONITOR: worker exited on signal %d, restarting...", WTERMSIG(status));
            else
                logmsg(LOG_ERR, "MONITOR: worker exited (stopped?) %d, restarting...", status);
        } else if (son == 0) {
#endif

            /* thread stuff */
            pthread_attr_init(&attr);
            pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

#ifdef  NEED_STACK
            /* set new stack size - necessary for OpenBSD/FreeBSD and Linux NPTL */
            if(pthread_attr_setstacksize(&attr, 1 << 18)) {
                logmsg(LOG_ERR, "can't set stack size - aborted");
                exit(1);
            }
#endif
            /* start timer */
            if(pthread_create(&thr, &attr, thr_timer, NULL)) {
                logmsg(LOG_ERR, "create thr_resurect: %s - aborted", strerror(errno));
                exit(1);
            }

            /* start the controlling thread (if needed) */
            if(control_sock >= 0 && pthread_create(&thr, &attr, thr_control, NULL)) {
                logmsg(LOG_ERR, "create thr_control: %s - aborted", strerror(errno));
                exit(1);
            }

            /* pause to make sure the service threads were started */
            sleep(1);

            /* create the worker threads */
            for(i = 0; i < numthreads; i++)
                if(pthread_create(&thr, &attr, thr_http, NULL)) {
                    logmsg(LOG_ERR, "create thr_http: %s - aborted", strerror(errno));
                    exit(1);
                }

            /* pause to make sure at least some of the worker threads were started */
            sleep(1);

            /* and start working */
            for(;;) {
                if(shut_down) {
                    logmsg(LOG_NOTICE, "shutting down...");
                    for(lstn = listeners; lstn; lstn = lstn->next)
                        close(lstn->sock);
                    if(grace > 0) {
                        sleep(grace);
                        logmsg(LOG_NOTICE, "grace period expired - exiting...");
                    }
                    if(ctrl_name != NULL)
                        (void)unlink(ctrl_name);
                    exit(0);
                }
                for(lstn = listeners, i = 0; i < n_listeners; lstn = lstn->next, i++) {
                    polls[i].events = POLLIN | POLLPRI;
                    polls[i].revents = 0;
                }
                if(poll(polls, n_listeners, -1) < 0) {
                    logmsg(LOG_WARNING, "poll: %s", strerror(errno));
                } else {
                    for(lstn = listeners, i = 0; lstn; lstn = lstn->next, i++) {
                        if(polls[i].revents & (POLLIN | POLLPRI)) {
                            memset(&clnt_addr, 0, sizeof(clnt_addr));
                            clnt_length = sizeof(clnt_addr);
                            if((clnt = accept(lstn->sock, (struct sockaddr *)&clnt_addr,
                                (socklen_t *)&clnt_length)) < 0) {
                                logmsg(LOG_WARNING, "HTTP accept: %s", strerror(errno));
                            } else if(((struct sockaddr_in *)&clnt_addr)->sin_family == AF_INET
                                   || ((struct sockaddr_in *)&clnt_addr)->sin_family == AF_INET6) {
                                thr_arg arg;

                                if(lstn->disabled) {
                                    /*
                                    addr2str(tmp, MAXBUF - 1, &clnt_addr, 1);
                                    logmsg(LOG_WARNING, "HTTP disabled listener from %s", tmp);
                                    */
                                    close(clnt);
                                }
                                arg.sock = clnt;
                                arg.lstn = lstn;
                                if((arg.from_host.ai_addr = (struct sockaddr *)malloc(clnt_length)) == NULL) {
                                    logmsg(LOG_WARNING, "HTTP arg address: malloc");
                                    close(clnt);
                                    continue;
                                }
                                memcpy(arg.from_host.ai_addr, &clnt_addr, clnt_length);
                                arg.from_host.ai_addrlen = clnt_length;
                                if(((struct sockaddr_in *)&clnt_addr)->sin_family == AF_INET)
                                    arg.from_host.ai_family = AF_INET;
                                else
                                    arg.from_host.ai_family = AF_INET6;
                                if(put_thr_arg(&arg))
                                    close(clnt);
                            } else {
                                /* may happen on FreeBSD, I am told */
                                logmsg(LOG_WARNING, "HTTP connection prematurely closed by peer");
                                close(clnt);
                            }
                        }
                    }
                }
            }
#ifdef  UPER
        } else {
            /* failed to spawn son */
            logmsg(LOG_ERR, "Can't fork worker (%s) - aborted", strerror(errno));
            exit(1);
        }
#endif
    }
}
Beispiel #30
0
int handle_accept(connection *con, uint32_t size, void* data) {
    accept_msg* amsg = (accept_msg*)data;
    char ipstr[32];

    int ret;
    acceptor_record* rec;

    //Lookup
    rec = &acc.instance_cache[GET_ACC_INDEX(amsg->iid)];

    //Found record previously written
    if (amsg->iid == rec->iid) {
        if(amsg->ballot >= rec->ballot) {
            L_DEBUG("accepting value for instance %d with ballot %d\n", amsg->iid, amsg->ballot);
            stablestorage_save_accept(amsg, rec);
            return send_learn_message(addr2str(ipstr, con->remoteaddr), con->remoteport, rec);
        } else {
            L_DEBUG("ignoring accept for instance %d with ballot %d, already given to ballot %d\n", amsg->iid, amsg->ballot, rec->ballot);
        }
        return 1;
    }

    //Record not found in acceptor array
    if (amsg->iid > rec->iid) {
        L_DEBUG("accepting value instance %d with ballot %d, never seen before\n", amsg->iid, amsg->ballot);
        stablestorage_save_accept(amsg, rec);
        return send_learn_message(addr2str(ipstr, con->remoteaddr), con->remoteport, rec);
    }

    //Record was overwritten in acceptor array
    //We must scan the logfile before accepting or not
    if (amsg->iid < rec->iid) {
        rec = stablestorage_get_record(amsg->iid);
        if (rec == NULL) {
            L_DEBUG("accepting value instance %d with ballot %d, never seen before [info from disk]\n", amsg->iid, amsg->ballot);
            rec = malloc(sizeof(acceptor_record));
            rec->value = NULL;
            stablestorage_save_accept(amsg, rec);
            ret = send_learn_message(addr2str(ipstr, con->remoteaddr), con->remoteport, rec);
            return ret;
        }

        if(amsg->ballot >= rec->ballot) {
            L_DEBUG("accepting value instance %d with ballot %d [info from disk]\n", amsg->iid, amsg->ballot);
            stablestorage_save_accept(amsg, rec);
            ret = send_learn_message(addr2str(ipstr, con->remoteaddr), con->remoteport, rec);
        } else {
            L_DEBUG("ignoring accept for instance %d with ballot %d, already given to ballot %d [info from disk]\n", amsg->iid, amsg->ballot, rec->ballot);
            ret = 0;
        }

        if(rec->value != NULL) {
            free(rec->value);
        }
        free(rec);

        return ret;
    }


}