int gulm_connect_csid(const char *csid, struct local_client **newclient)
{
    int fd;
    struct sockaddr_in6 addr;
    int status;
    int one = 1;

    DEBUGLOG("Connecting socket\n");
    fd = socket(PF_INET6, SOCK_STREAM, 0);

    if (fd < 0)
    {
	syslog(LOG_ERR, "Unable to create new socket: %m");
	return -1;
    }

    addr.sin6_family = AF_INET6;
    memcpy(&addr.sin6_addr, csid, GULM_MAX_CSID_LEN);
    addr.sin6_port = htons(tcp_port);

    DEBUGLOG("Connecting socket %d\n", fd);
    if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in6)) < 0)
    {
	/* "Connection refused" is "normal" because clvmd may not yet be running
	 * on that node.
	 */
	if (errno != ECONNREFUSED)
	{
	    syslog(LOG_ERR, "Unable to connect to remote node: %m");
	}
	DEBUGLOG("Unable to connect to remote node: %s\n", strerror(errno));
	close(fd);
	return -1;
    }

    /* Set Close-on-exec */
    fcntl(fd, F_SETFD, 1);
    setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(int));

    status = alloc_client(fd, csid, newclient);
    if (status)
	close(fd);
    else
	add_client(*newclient);

    /* If we can connect to it, it must be running a clvmd */
    gulm_add_up_node(csid);
    return status;
}
/* Read on main comms (listen) socket, accept it */
int cluster_fd_gulm_callback(struct local_client *fd, char *buf, int len, const char *csid,
			struct local_client **new_client)
{
    int newfd;
    struct sockaddr_in6 addr;
    socklen_t addrlen = sizeof(addr);
    int status;
    char name[GULM_MAX_CLUSTER_MEMBER_NAME_LEN];

    DEBUGLOG("cluster_fd_callback\n");
    *new_client = NULL;
    newfd = accept(listen_fd, (struct sockaddr *)&addr, &addrlen);

    DEBUGLOG("cluster_fd_callback, newfd=%d (errno=%d)\n", newfd, errno);
    if (!newfd)
    {
	syslog(LOG_ERR, "error in accept: %m");
	errno = EAGAIN;
	return -1; /* Don't return an error or clvmd will close the listening FD */
    }

    /* Check that the client is a member of the cluster
       and reject if not.
    */
    if (gulm_name_from_csid((char *)&addr.sin6_addr, name) < 0)
    {
	syslog(LOG_ERR, "Got connect from non-cluster node %s\n",
	       print_csid((char *)&addr.sin6_addr));
	DEBUGLOG("Got connect from non-cluster node %s\n",
		 print_csid((char *)&addr.sin6_addr));
	close(newfd);

	errno = EAGAIN;
	return -1;
    }

    status = alloc_client(newfd, (char *)&addr.sin6_addr, new_client);
    if (status)
    {
	DEBUGLOG("cluster_fd_callback, alloc_client failed, status = %d\n", status);
	close(newfd);
	/* See above... */
	errno = EAGAIN;
	return -1;
    }
    DEBUGLOG("cluster_fd_callback, returning %d, %p\n", newfd, *new_client);
    return newfd;
}
Ejemplo n.º 3
0
CAMLprim value stub_asl_open(value ident, value facility, value stderr, value no_delay, value no_remote) {
  CAMLparam5(ident, facility, stderr, no_delay, no_remote);
  const char *c_ident = String_val(ident);
  const char *c_facility = String_val(facility);
  uint32_t options =
      (Bool_val(stderr)?ASL_OPT_STDERR:0)
    | (Bool_val(no_delay)?ASL_OPT_NO_DELAY:0)
    | (Bool_val(no_remote)?ASL_OPT_NO_REMOTE:0);
  aslclient asl = NULL;

  caml_release_runtime_system();
  asl = asl_open(c_ident, c_facility, options);
  caml_acquire_runtime_system();

  CAMLreturn(alloc_client(asl));
}
Ejemplo n.º 4
0
/*
 * Create a new struct Client structure and set it to initial state.
 *
 *   from == NULL,   create local client (a client connected to a socket).
 *
 *   from != NULL,   create remote client (behind a socket associated with
 *                   the client defined by 'from').
 *                   ('from' is a local client!!).
 */
struct Client* make_client(struct Client *from, int status)
{
  struct Client* cptr = 0;
  struct Connection* con = 0;

  assert(!from || cli_verify(from));

  cptr = alloc_client();

  assert(0 != cptr);
  assert(!cli_magic(cptr));
  assert(0 == from || 0 != cli_connect(from));

  if (!from) { /* local client, allocate a struct Connection */
    con = alloc_connection();

    assert(0 != con);
    assert(!con_magic(con));

    con_magic(con) = CONNECTION_MAGIC;
    con_fd(con) = -1; /* initialize struct Connection */
    con_freeflag(con) = 0;
    con_nextnick(con) = CurrentTime - NICK_DELAY;
    con_nexttarget(con) = CurrentTime - (TARGET_DELAY * (STARTTARGETS - 1));
    con_handler(con) = UNREGISTERED_HANDLER;
    con_client(con) = cptr;

    cli_local(cptr) = 1; /* Set certain fields of the struct Client */
    cli_since(cptr) = cli_lasttime(cptr) = cli_firsttime(cptr) = CurrentTime;
    cli_lastnick(cptr) = TStime();
  } else
    con = cli_connect(from); /* use 'from's connection */

  assert(0 != con);
  assert(con_verify(con));

  cli_magic(cptr) = CLIENT_MAGIC;
  cli_connect(cptr) = con; /* set the connection and other fields */
  cli_status(cptr) = status;
  cli_hnext(cptr) = cptr;
  strcpy(cli_username(cptr), "unknown");

  return cptr;
}
Ejemplo n.º 5
0
static void new_client(evutil_socket_t lsn_fd, short event, void *arg)
{
    struct event_base *ev_base = (struct event_base *)arg;
    struct sockaddr_in clt_addr;
    socklen_t addr_len = sizeof(clt_addr);
    int fd = accept(lsn_fd, (struct sockaddr*)&clt_addr, &addr_len);
    if (fd == -1) {
        logging("accept new client error %s", strerror(errno));
        return;
    }
    int id = alloc_client();
    if (id == -1) {
        logging("clients is already full");
        return;
    }
    strcpy(AllChannels[id]._peer_ip, inet_ntoa(clt_addr.sin_addr));

    evutil_make_socket_nonblocking(fd);
    AllChannels[id]._bev = bufferevent_socket_new(ev_base, fd, BEV_OPT_CLOSE_ON_FREE);
    bufferevent_setcb(AllChannels[id]._bev, readcb, NULL, errorcb, (void *)(intptr_t)id);
    bufferevent_enable(AllChannels[id]._bev, EV_READ|EV_WRITE);
}
Ejemplo n.º 6
0
CAMLprim value stub_asl_open_null(){
  CAMLparam0();
  CAMLreturn(alloc_client(NULL));
}
Ejemplo n.º 7
0
int main(void) {

    int i;
    int ifd;
    int len;
    int client_sock;
    struct online_user *user;
    Client client;
    struct sockaddr_in client_name;
    int client_name_len = sizeof(client_name);
#define MAX_BUFSIZE	0x100000
    char buf[MAX_BUFSIZE];
    struct format *package = (struct format *)buf;

    tcp_server_sock = tcp_startup(SERVER_TCP_PORT);

    init_mysql();
    register_ctrl_c();

    kdpfd = epoll_create(MAXEPOLLSIZE);

    /* 设置要监听的事件。EPOLLIN 表示可读,EPOLLET则指定电平触发 */
    ev.events = EPOLLIN;
    ev.data.fd = tcp_server_sock;

    if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, tcp_server_sock, &ev) < 0)
        /* 把 tcp sock 加入监听集合,以便接收连接请求 */
        error_die("tcp epoll_ctl\n");

    /* 记录监听的文件数,同时他也是 epoll_wait 的第三个参数。
       因为内核需要知道 events 数组的有效数据有多长 */
    curfds = 1;

    for (;;) {

        memset(buf,0,sizeof(buf));
        printf("waiting...\n");

        /* 等待有事件发生。该函数的返回值存放在 nfds 和 events 内 */
        nfds = epoll_wait(kdpfd, events, curfds, -1);

        if (nfds < 0)
            error_die("epoll_wait");

        for (i = 0; i < nfds; i++) {

            ifd = events[i].data.fd;

            if (ifd == tcp_server_sock) {
                //新的 TCP 连接请求到来

                if (!(events[i].events & EPOLLIN))
                    error_die("failed to event is not EPOLLIN\n");

                client_sock = accept(tcp_server_sock,(struct sockaddr *)&client_name,&client_name_len);
                setnonblocking(client_sock);

                ev.events  = EPOLLIN;
                ev.data.fd = client_sock;
                if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, client_sock, &ev) < 0)
                    error_die("epoll_ctl");

                curfds++;

                client = alloc_client(client_sock);
                add_client(client);

            } else if ((events[i].events & EPOLLIN)) {
                /* 客户端有数据发来(POLLIN)或者发生 POLLHUP/POLLERR(这两个事件系统会自动监听) */

                client = find_client(ifd);

                if (client != NULL && client->handler != NULL) {
                    //已经有了处理函数,直接调用这个函数来处理
                    client->handler(ifd,client->private);
                } else {
                    //默认的处理方法

                    //读入数据包头部。
                    len = read(ifd,package,(sizeof(struct format)-sizeof(package->data)));

                    if (len <= 0) {
                        //对方断线。
                        close_connect(ifd);
                        continue;
                    }

                    if (package->length >= MAX_BUFSIZE || package->length <= 0) {

                        while(read(ifd,package->data,4) > 0);
                        continue;
                    }

                    if ((len = read(ifd,package->data,package->length) <= 0)) {
                        //读入数据包内容

                        close_connect(ifd);
                        continue;
                    }

                    // 处理数据
                    if (handle(ifd,package) == NEED_WRITE) {

                        ev.events = EPOLLOUT;
                        ev.data.fd = ifd;
                        epoll_ctl(kdpfd,EPOLL_CTL_MOD,ifd,&ev);
                    }
                }

            } else if(events[i].events & EPOLLOUT) {