Beispiel #1
0
// return type
static int
ctrl_cmd(struct socket_server *ss, struct socket_message *result) {
    int fd = ss->recvctrl_fd;
    // the length of message is one byte, so 256+8 buffer size is enough.
    uint8_t buffer[256];
    uint8_t header[2];
    block_readpipe(fd, header, sizeof(header));
    int type = header[0];
    int len = header[1];
    block_readpipe(fd, buffer, len);
    // ctrl command only exist in local fd, so don't worry about endian.
    switch (type) {
    case 'S':
        return start_socket(ss,(struct request_start *)buffer, result);
    case 'B':
        return bind_socket(ss,(struct request_bind *)buffer, result);
    case 'L':
        return listen_socket(ss,(struct request_listen *)buffer, result);
    case 'K':
        return close_socket(ss,(struct request_close *)buffer, result);
    case 'O':
        return open_socket(ss, (struct request_open *)buffer, result);
    case 'X':
        result->opaque = 0;
        result->id = 0;
        result->ud = 0;
        result->data = NULL;
        return SOCKET_EXIT;
    case 'D':
        return send_socket(ss, (struct request_send *)buffer, result, PRIORITY_HIGH, NULL);
    case 'P':
        return send_socket(ss, (struct request_send *)buffer, result, PRIORITY_LOW, NULL);
    case 'A': {
        struct request_send_udp * rsu = (struct request_send_udp *)buffer;
        return send_socket(ss, &rsu->send, result, PRIORITY_HIGH, rsu->address);
    }
    case 'C':
        return set_udp_address(ss, (struct request_setudp *)buffer, result);
    case 'T':
        setopt_socket(ss, (struct request_setopt *)buffer);
        return -1;
    case 'U':
        add_udp_socket(ss, (struct request_udp *)buffer);
        return -1;
    default:
        fprintf(stderr, "socket-server: Unknown ctrl %c.\n",type);
        return -1;
    };

    return -1;
}
/*
 *
 * Extern connect to afpd parameter, can be called multiple times for multiple listeners (up to MAX_UDP_SOCKS times)
 *
 * */
int fce_add_udp_socket(const char *target)
{
	const char *port = FCE_DEFAULT_PORT_STRING;
	char target_ip[256] = {""};

	strncpy(target_ip, target, sizeof(target_ip) -1);

	char *port_delim = strchr( target_ip, ':' );
	if (port_delim) {
		*port_delim = 0;
		port = port_delim + 1;
	}
	return add_udp_socket(target_ip, port);
}
void server_init (engine_t *E, server_functions_t *F, conn_type_t *listen_connection_type, void *listen_connection_extra) {
  if (F != NULL) {
    if (F->sighup) {
      sf.sighup = F->sighup;
    }
    if (F->sigusr1) {
      sf.sigusr1 = F->sigusr1;
    }
    if (F->save_index) {
      sf.save_index = F->save_index;
    }
    if (F->cron) {
      sf.cron = F->cron;
    }
  }
  
  init_epoll ();
  init_netbuffers ();
  if (udp_enabled) {
    init_msg_buffers (0);
  }
  
  if (daemonize) {
    setsid ();
    reopen_logs ();
  }

  if (!E->sfd) {
    E->sfd = server_socket (port, E->settings_addr, backlog, 0);
  }

  if (E->sfd < 0) {
    kprintf ("cannot open server socket at port %d: %m\n", port);
    exit (1);
  }

  if (change_user (username) < 0) {
    kprintf ("fatal: cannot change user to %s\n", username ? username : "******");
    exit (1);
  }

  if (binlogname && !binlog_disabled) {
    assert (append_to_binlog (Binlog) == log_readto_pos);
  }

  init_listening_connection (E->sfd, listen_connection_type, listen_connection_extra);
  if (udp_enabled) {
    add_udp_socket (port, 0);
  }
  
  if (binlog_disabled && binlog_fd >= 0) {
    epoll_pre_event = read_new_events;
  }

  struct sigaction sa;
  memset (&sa, 0, sizeof (sa));
  sa.sa_handler = sigint_handler;
  sigemptyset (&sa.sa_mask);
  sigaddset (&sa.sa_mask, SIGTERM); 
  sigaction (SIGINT, &sa, NULL);
  
  sa.sa_handler = sigterm_handler;
  sigemptyset (&sa.sa_mask);
  sigaddset (&sa.sa_mask, SIGINT);
  sigaction (SIGTERM, &sa, NULL);
  
  sa.sa_handler = SIG_IGN;
  sigaction (SIGPIPE, &sa, NULL);
  sigaction (SIGPOLL, &sa, NULL);
  
  if (daemonize) {
    sa.sa_handler = sighup_handler;
    sigemptyset (&sa.sa_mask);
    sigaction (SIGHUP, &sa, NULL);
  }
}
Beispiel #4
0
// return type
// 执行管道指令,写入socket_message
static int
ctrl_cmd(struct socket_server *ss, struct socket_message *result) {
	int fd = ss->recvctrl_fd;
	// the length of message is one byte, so 256+8 buffer size is enough.
	// 读管道数据,相反的数据写入管道逻辑见send_request方法
	// len长度1个字节,所以缓冲区的长度为256足够
	uint8_t buffer[256];
	uint8_t header[2];
	// 先读2字节的头
	block_readpipe(fd, header, sizeof(header));
	int type = header[0];
	int len = header[1];
	// 再读剩余数据部分
	block_readpipe(fd, buffer, len);
	// ctrl command only exist in local fd, so don't worry about endian.
	switch (type) {
	case 'S':
		// PACCEPT -> CONNECTED 
		// PLISTEN -> LISTEN
		// 把套接字加入事件循环
		return start_socket(ss,(struct request_start *)buffer, result);
	case 'B':
		// 绑定套接字
		return bind_socket(ss,(struct request_bind *)buffer, result);
	case 'L':
		// 监听套接字
		return listen_socket(ss,(struct request_listen *)buffer, result);
	case 'K':
		// 关闭套接字
		return close_socket(ss,(struct request_close *)buffer, result);
	case 'O':
		// 打开套接字
		return open_socket(ss, (struct request_open *)buffer, result);
	case 'X':
		// 退出套接字
		result->opaque = 0;
		result->id = 0;
		result->ud = 0;
		result->data = NULL;
		return SOCKET_EXIT;
	case 'D':
		// 发送高优先级数据
		return send_socket(ss, (struct request_send *)buffer, result, PRIORITY_HIGH, NULL);
	case 'P':
		// 发送低优先级数据
		return send_socket(ss, (struct request_send *)buffer, result, PRIORITY_LOW, NULL);
	case 'A': {
		struct request_send_udp * rsu = (struct request_send_udp *)buffer;
		return send_socket(ss, &rsu->send, result, PRIORITY_HIGH, rsu->address);
	}
	case 'C':
		return set_udp_address(ss, (struct request_setudp *)buffer, result);
	case 'T':
		// 设置套接字
		setopt_socket(ss, (struct request_setopt *)buffer);
		return -1;
	case 'U':
		add_udp_socket(ss, (struct request_udp *)buffer);
		return -1;
	default:
		fprintf(stderr, "socket-server: Unknown ctrl %c.\n",type);
		return -1;
	};

	return -1;
}