예제 #1
0
/**
 * [Client only]
 * Setup the configuration for the server this client is connecting to:
 *   - Get server host and port.
 *   - Get address of server.
 *
 * server: Of the form server_host:server_port. The server to connect to.
 *         If no port is specified, defaults to port 80.
 * returns: 0 on success, -1 otherwise.
 */
int do_config_server(char *server) { ASSERT_CLIENT_ONLY;
  /* Parse server into its hostname and port. */
  char *host, *server_port_str, *_server = server;
  int server_port;
  host = strsep(&server, ":");
  if (server == NULL) {
    fprintf(stderr, "[ERROR] No port specified for server %s\n", host);
    return -1;
  }
  server_port_str = strsep(&server, ":");
  server_port = atoi(server_port_str);
  config->sconn = calloc(sizeof(conn_t), 1);
  conn_add(config->sconn);

  /* Get IP address of server. See if this is a server on the same machine. */
  in_addr_t dst_ip = ip_from_hostname(_server);
  if (dst_ip == 0)
    return -1;
  else if (dst_ip != LOCALHOST)
    unix_socket = false;

  /* Set up connection details. */
  int port = server_port == 0 ? DEFAULT_PORT : server_port;
  conn_setup(config->sconn, dst_ip, port, unix_socket);

  return 0;
}
예제 #2
0
/**
 * [Server only]
 * Handle a new connection from a client. Set up connection details and
 * initialize sequence numbers.
 *
 * pkt: The SYN segment from the client.
 * returns: The conn_t associated with the new connection.
 */
conn_t *tcp_new_connection(char *pkt) { ASSERT_SERVER_ONLY;
  /* Ignore if too many clients are connected. */
  if (num_connected >= MAX_NUM_CLIENTS) {
    fprintf(stderr, "[ERROR] Maximum number of clients (%d) reached\n",
            MAX_NUM_CLIENTS);
    return NULL;
  }
  num_connected++;

  iphdr_t *ip_hdr = (iphdr_t *) pkt;
  tcphdr_t *syn = (tcphdr_t *) (pkt + IP_HDR_SIZE);

  /* Set up connection details and add to list of connections. */
  conn_t *conn = calloc(sizeof(conn_t), 1);
  conn_setup(conn, ntohl(ip_hdr->saddr), ntohs(syn->th_sport), unix_socket);
  conn->their_init_seqno = ntohl(syn->th_seq);
  conn->ackno = conn->their_init_seqno + 1;
  conn_add(conn);

  /* Send a SYN-ACK to the client. */
  send_synack(conn);

  /* Get window size of the client. */
  ctcp_cfg->send_window = ntohs(syn->window);
  ctcp_config_t *config_copy = calloc(sizeof(ctcp_config_t), 1);
  memcpy(config_copy, ctcp_cfg, sizeof(ctcp_config_t));

  /* Student code. */
  ctcp_state_t *state = ctcp_init(conn, config_copy);
  conn->state = state;

  fprintf(stderr, "[INFO] Client connected\n");
  return conn;
}
예제 #3
0
static int add_conn(struct iscsi_target *target, unsigned long ptr)
{
	int err;
	struct iscsi_session *session;
	struct conn_info info;

	if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0)
		return err;

	if (!(session = session_lookup(target, info.sid)))
		return -ENOENT;

	return conn_add(session, &info);
}
예제 #4
0
파일: config.c 프로젝트: kissthink/IET
/* 连接信息从用户态转入内核态 */
static int add_conn(struct iscsi_target *target, unsigned long ptr)
{
	struct iscsi_session *session;
	struct conn_info info;
	int err;

	/* 拷贝用户态连接信息 */
	err = copy_from_user(&info, (void *) ptr, sizeof(info));
	if (err)
		return -EFAULT;

	/* 根据target和用户态连接信息中的会话id, 找到会话信息 */
	session = session_lookup(target, info.sid);
	if (!session)
		return -ENOENT;

	return conn_add(session, &info);
}
예제 #5
0
static void
conn_main(void)
{
  const AtmAddr_t *addr;
  int main_conn;
  const char *str;
  int i;

  addr = get_var_addr(&conn_unit, "S1");
  if (addr == NULL) {
    dump_printf(EL_ERROR, "S1 (LES Address) must be specified");
    event_put(&conn_unit, CE_EXIT, NULL);
  }
  else {
    str = get_var_str(&conn_unit,"S2");
    if (str == NULL) {
      set_var_str(&conn_unit, "S2", S2_default);
    }
    i = get_var_int(&conn_unit,"S3");
    if (i == 0) {
      set_var_int(&conn_unit,"S3", S3_default);
    }
    i = get_var_int(&conn_unit,"S4");
    if (i == 0) {
      set_var_int(&conn_unit,"S4", S4_default);
    }
    i = get_var_int(&conn_unit,"S5");
    if (i == 0) {
      set_var_int(&conn_unit,"S5", S5_default);
    }
    addr = get_var_addr(&conn_unit, "S6");
    if (addr == NULL) {
      dump_printf(EL_ERROR, "S6 (BUS Address) must be specified");
      event_put(&conn_unit, CE_EXIT, NULL);
    } else {
      main_conn = atm_create_socket(CONTROL_DIRECT, 
				    get_var_addr(&conn_unit, "S1"));
      if (main_conn >= 0) {
	(void)conn_add(CT_MAIN, main_conn,0);
      }
    }
  }
}
예제 #6
0
파일: upssched.c 프로젝트: AlexLov/nut
static void start_daemon(int lockfd)
{
	int	maxfd, pid, pipefd, ret;
	struct	timeval	tv;
	fd_set	rfds;
	conn_t	*tmp, *tmpnext;

	us_serialize(SERIALIZE_INIT);

	if ((pid = fork()) < 0)
		fatal_with_errno(EXIT_FAILURE, "Unable to enter background");

	if (pid != 0) {		/* parent */

		/* wait for child to set up the listener */
		us_serialize(SERIALIZE_WAIT);

		return;
	}

	/* child */

	close(0);
	close(1);
	close(2);

	/* make fds 0-2 point somewhere defined */
	if (open("/dev/null", O_RDWR) != 0)
		fatal_with_errno(EXIT_FAILURE, "open /dev/null");

	if (dup(0) == -1)
		fatal_with_errno(EXIT_FAILURE, "dup");

	if (dup(0) == -1)
		fatal_with_errno(EXIT_FAILURE, "dup");

	pipefd = open_sock();

	if (verbose)
		upslogx(LOG_INFO, "Timer daemon started");

	/* release the parent */
	us_serialize(SERIALIZE_SET);

	/* drop the lock now that the background is running */
	unlink(lockfn);
	close(lockfd);

	/* now watch for activity */

	for (;;) {
		/* wait at most 1s so we can check our timers regularly */
		tv.tv_sec = 1;
		tv.tv_usec = 0;

		FD_ZERO(&rfds);
		FD_SET(pipefd, &rfds);

		maxfd = pipefd;

		for (tmp = connhead; tmp != NULL; tmp = tmp->next) {
			FD_SET(tmp->fd, &rfds);

			if (tmp->fd > maxfd)
				maxfd = tmp->fd;
		}

		ret = select(maxfd + 1, &rfds, NULL, NULL, &tv);

		if (ret > 0) {

			if (FD_ISSET(pipefd, &rfds))
				conn_add(pipefd);

			tmp = connhead;

			while (tmp) {
				tmpnext = tmp->next;

				if (FD_ISSET(tmp->fd, &rfds)) {
					if (sock_read(tmp) < 0) {
						close(tmp->fd);
						conn_del(tmp);
					}
				}

				tmp = tmpnext;
			}
		}

		checktimers();
	}
}
예제 #7
0
파일: echosrv.cpp 프로젝트: lcnight/lcnight
int main(int argc, char *argv[])
{
    int echo_port = PORT;
    if(argc > 1) {
        LOG("IN %d OUT %d RDHUP %d HUP %d ERR %d", EPOLLIN, EPOLLOUT, EPOLLRDHUP, EPOLLHUP, EPOLLERR);
        char *endptr = NULL;
        echo_port = strtol(argv[1], &endptr, 10);
        if (echo_port <= 0 || echo_port >= LONG_MAX) {
            LOG("LONG_MIN %ld LONG_MAX %ld, echo port %d", LONG_MIN, LONG_MAX, echo_port);
            exit(-1);
        }
    }
    LOG("listen to localhost:%d\n", echo_port);

    // 处理信号
    register_sig(SIGTERM, signal_handler);
    register_sig(SIGINT, signal_handler);
    register_sig(SIGQUIT, signal_handler);
    register_sig(SIGPIPE, SIG_IGN);
    /* 设置SIGURG 的处理函数 sig_urg */
    //if(fcntl(ss_fd, F_SETOWN, getpid()) < 0) {
        //perror("can not set OOB own");
    //}
    //register_sig(SIGURG, signal_handler);

    int ss_fd = -1;
    struct sockaddr_in server_addr = {0};
    struct sockaddr_in client_addr = {0};
    socklen_t addr_in_len = sizeof(struct sockaddr_in);
    int yes = 1;
    ss_fd = socket( AF_INET, SOCK_STREAM, 0);
    if(ss_fd == -1){
        perror("create server socket error");
        return EXIT_FAILURE;
    }

    if (setsockopt(ss_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
        perror("setsockopt");
        return EXIT_FAILURE;
    }

    memset(&server_addr, 0, sizeof(struct sockaddr_in));
    memset(&client_addr, 0, sizeof(struct sockaddr_in));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(echo_port);
    server_addr.sin_addr.s_addr = htons(INADDR_ANY);

    if (bind(ss_fd, (struct sockaddr *)&server_addr, addr_in_len) == -1) {
        perror("bind server socket error");
        return EXIT_FAILURE;
    } else {
        printf("bind successfully \n");
    }

    if (listen(ss_fd, BACKLOG) == -1) {
        perror("listen server socket error");
        return EXIT_FAILURE;
    } else {
        printf("listen successfully \n");
    }

    printf("listen port %d\n", echo_port);

    struct epoll_event ev = {0};
    struct epoll_event  events[MAXEVENTS] = {{0}};

    int epfd = epoll_create(MAXCLIENTS);
    //add server socket to epoll
    ev.events = EPOLLIN ; //| EPOLLET;
    ev.data.fd = ss_fd;
    if(setnonblocking(ss_fd) != 0) {
        perror("css_fd an not nonblocking");
        return EXIT_FAILURE;
    }
    epoll_ctl(epfd, EPOLL_CTL_ADD, ss_fd, &ev);
    if(epfd == -1){
        perror("epoll listen socket");
        return EXIT_FAILURE;
    }

#define     E_TIMEOUT       10
    /***********************************  main loop  **************************************/
    while(!closing) {
        int ready_fds = epoll_wait(epfd, events, MAXEVENTS, E_TIMEOUT);
        if(ready_fds == -1){
            perror("epoll_wait");
            break;
        }

        for(int n = 0; n < ready_fds; ++n) {
            if (events[n].events & EPOLLERR || events[n].events & EPOLLRDHUP || events[n].events & EPOLLHUP) {
                D_L("ERROR or HUP\n");
                if (events[n].data.fd != ss_fd) {
                    closeclient(epfd, events[n].data.fd);
                }
                continue;
            }
            if (events[n].events & EPOLLIN) {
                if(events[n].data.fd == ss_fd) { //listening socket
                    while(true) {
                        int c_fd = accept(ss_fd, (struct sockaddr *) &client_addr, &addr_in_len);
                        if(c_fd < 0){
                            if(errno == EAGAIN){
                                break;
                            } else if(errno == EINTR){
                                continue;
                            } else {
                                D_L("accept error %s", strerror(errno));
                                close(ss_fd);
                                break;
                            }
                        } 
                        setnonblocking(c_fd);
                        setkeepalive(c_fd);

                        ev.events = EPOLLET | EPOLLIN | EPOLLOUT | EPOLLRDHUP;
                        ev.data.fd = c_fd;

                        //add to epoll events queue
                        if (STAT.conn_amount < MAXCLIENTS) {
                            D_L("total [%d] client, new fd %d Addr: %s:%d", STAT.conn_amount, c_fd,\
                                    inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

                            if (epoll_ctl(epfd, EPOLL_CTL_ADD, c_fd, &ev) < 0) {
                                fprintf(stderr, "epoll set insertion error: fd=%d", c_fd);
                                break;
                            }

                            conn_add(c_fd);
                        } else {
                            const char *refuse_str = "max connections, refuse and close, bye";
                            D_L("%s\n", refuse_str);
                            send(c_fd, refuse_str, strlen(refuse_str), 0);
                            close(c_fd);
                        }
                    }
                } else { //common client
                    int fd = events[n].data.fd;
                    conn_list_iter it = conn_list.find(fd);
                    if (it != conn_list.end()) {
                        int left_sz = MAX_BUFSZ - it->second.rsize;
                        int rsz = recv(fd, it->second.rbuf + it->second.rsize, left_sz, 0);
                        if (rsz <= 0) {
                            D_L("get from fd %d err: %s, close it", fd, strerror(errno));
                            closeclient(epfd, fd);
                            continue;
                        } else if (rsz < left_sz) {
                            //D_L("get from fd %d len: %d", fd, rsz);
                            it->second.rsize += rsz;
                        } else {
                            D_L("recv buf size is to small for bufsz %d fd %d len %d", MAX_BUFSZ, fd, rsz);
                            closeclient(epfd, fd);
                            continue;
                        }
                    } else {
                        D_L("get unknown fd %d EPOLLIN", fd);
                    }
                }
            }
            if (events[n].events & EPOLLOUT) {
                int fd = events[n].data.fd;
                conn_list_iter it = conn_list.find(fd);
                if (it != conn_list.end()) {
                    if (it->second.wsize == 0 && it->second.rsize == 0) {
                        continue;
                    }
                    int nop_sz = it->second.rsize;
                    int left_sz = MAX_BUFSZ - it->second.wsize;
                    if (nop_sz > left_sz) { //buffer too small, send first
                        int wsz = send(fd, it->second.wbuf, it->second.wsize, 0);
                        if (wsz < 0) {
                            D_L("send to fd %d err: %s", fd, strerror(errno));
                            if (errno == EINTR || errno == EAGAIN) {
                                continue;
                            } 
                            closeclient(epfd, fd);
                            continue;
                        }
                        if (wsz != it->second.wsize) {
                            memmove(it->second.wbuf, it->second.wbuf + wsz, it->second.wsize - wsz);
                        }
                        it->second.wsize -= wsz;
                    }
                    left_sz = MAX_BUFSZ - it->second.wsize;
                    if (nop_sz > left_sz) {
                        D_L("send buf size to small for fd %d nop_size %d left_size %d", fd, nop_sz, left_sz);
                        closeclient(epfd, fd);
                        continue;
                    }
                    memcpy(it->second.wbuf + it->second.wsize, it->second.rbuf, nop_sz);
                    it->second.wsize += nop_sz;
                    it->second.rsize -= nop_sz;
                    char *buf = it->second.wbuf;
                    int wsz = send(fd, buf, it->second.wsize, 0);
                    if (wsz < 0) {
                        if (errno == EINTR || errno == EAGAIN) {
                            continue;
                        } 
                        D_L("send to fd %d err: %s, close it", fd, strerror(errno));
                        closeclient(epfd, fd);
                        continue;
                    }
                    it->second.wsize -= wsz;
                } else {
                    D_L("get unknown fd %d EPOLLOUT", fd);
                    closeclient(epfd, fd);
                }
            } 
            //D_L("unkown events get fd %d:%x", events[n].data.fd, events[n].events);
        }
    }
    close(epfd);
    return 0;
}
예제 #8
0
/*
 * Handle new connections or data arrival
 * data points to Conn_t
 */
static int
data_handler(const Event_t *event, void *funcdata)
{
  Conn_t *tmp, *newconn;
  int fd, nbytes;
  static char buffer[BUFSIZE];
  LaneControl_t *ctmp;
  struct sockaddr_atmsvc addr;

  assert(event->data != NULL);
  tmp = (Conn_t *)event->data;
  dump_conn(tmp);
  if (tmp->type == CT_MAIN) {
    nbytes = sizeof(addr);
    memset(&addr,0, nbytes);
    fd = accept(tmp->fd, (struct sockaddr *)&addr, &nbytes);
    if (fd <0) {
      dump_error(&conn_unit, "accept");
      if (errno == ENETRESET) {
	Debug_unit(&conn_unit,"Restart. Sleeping 10 secs...");
	sleep(10);
	event_put(&conn_unit, CE_RESTART, NULL);
      } else if (errno == EUNATCH) {
	Debug_unit(&conn_unit,"Exiting...");
	event_put(&conn_unit, CE_EXIT, NULL);
      }
      return -1;
    }
    newconn = conn_add(CT_SVC_CD, fd,0);
    newconn->state = call_state(CE_SVC_OPEN, 0, newconn);
  }
  else {
    /* tmp->fd or tmp->sfd ?*/
    nbytes = read(tmp->active_fd, buffer, BUFSIZE);
    if (nbytes < 0) {
      dump_error(&conn_unit, "read");
      if (errno == EUNATCH)
	event_put(&conn_unit, CE_EXIT, NULL);
      if (errno == ENETRESET) {
	Debug_unit(&conn_unit, "Restart. Sleeping 10 secs...");
	sleep(10);
	event_put(&conn_unit, CE_RESTART, NULL);
      }
    } else if (nbytes == 0) {
      /* EOF */
      Debug_unit(&conn_unit, "EOF");
      tmp->state = call_state(CE_SVC_CLOSE, 0, tmp);
    } else {
      buffer[nbytes] = '\0';
      Debug_unit(&conn_unit, "Data: %2.2x %2.2x %2.2x", 
		 0xff&buffer[0],0xff&buffer[1],0xff&buffer[2]);
      ctmp = (LaneControl_t *)buffer;
      if (is_control(ctmp) == 1) {
	control_packet = (LaneControl_t*)buffer;
	dump_control(ctmp);
	tmp->proxy = is_proxy();
	tmp->state = call_state(CE_DATA, ctmp->opcode, tmp);
      } else
	Debug_unit(&conn_unit,"Not a control_packet, discarding...");
    }
  }
  mem_free(&conn_unit, event);
  return 1;
}