int main(int argc, char *argv[]) { int i; init(); /* Init some variables (like malloc timestamp string, encrypt text string, etc.) */ check_par(argc, argv); /* Check command arguments number */ open_config(argv); /* Open config file and check if it failed */ open_log(argv); /* Open log file and check if it failed */ get_ipaddr(); /* Get server IP address */ create_socket(); /* Create a socket */ bind_socket(); /* Bind the socket */ listen_socket(); /* Listen at the socket */ print_server_info(); /* Print server information */ while (TRUE) { /* Read until the end of file */ if (read_flag) { if (fscanf(fcfg, "%s", enc_txt) == EOF) { finish_flag = 1; break; } else { fscanf(fcfg, "%s", dec_txt); } } read_flag = 0; init_select(); /* Select function */ if (select_func() == -1) break; for (i = 0; i < max_fds + 1; i++) { if (FD_ISSET(i, &rfds)) { if (i == sockfd) { /* If have a new client connect */ if (accept_new_cli() == -1) break; /* Try to accept new client */ if (check_connect() == -1) break; /* Check connect message from client */ if (print_client_info() == -1) break; /* Print the information of client side */ store_client_ip(); /* Store the client ip address */ break; } else { /* If have new message from client side */ client_ip = get_host_by_sockfd(i); /* Get the client ip address by socket */ recv_socket_msg(i, recv_mark); /* Get the message from socket */ handle_client_msg(i); /* Handle client message (SUCCESS_MSG, FAILURE_MSG, DISPATCH_MSG, etc.) */ break; } } if (main_flag == EXIT_FAILURE) break; } if (main_flag == EXIT_FAILURE) break; } remained_cli = ask_clients_quit(); /* Ask clients quit and count the remain clients number */ wait_clients_quit(); /* Wait for all clients quit */ quit_server(); /* Clean up and quit server, also print the message to log */ return main_flag; }
/* auth reply from main process */ static int recv_cookie_auth_reply(worker_st * ws) { unsigned i; int ret; int socketfd = -1; AuthReplyMsg *msg = NULL; PROTOBUF_ALLOCATOR(pa, ws); ret = recv_socket_msg(ws, ws->cmd_fd, AUTH_COOKIE_REP, &socketfd, (void *)&msg, (unpack_func) auth_reply_msg__unpack); if (ret < 0) { oclog(ws, LOG_ERR, "error receiving auth reply message"); return ret; } oclog(ws, LOG_DEBUG, "received auth reply message (value: %u)", (unsigned)msg->reply); switch (msg->reply) { case AUTH__REP__OK: if (socketfd != -1) { ws->tun_fd = socketfd; if (msg->vname == NULL || msg->user_name == NULL) { ret = ERR_AUTH_FAIL; goto cleanup; } strlcpy(ws->vinfo.name, msg->vname, sizeof(ws->vinfo.name)); strlcpy(ws->username, msg->user_name, sizeof(ws->username)); if (msg->group_name != NULL) { strlcpy(ws->groupname, msg->group_name, sizeof(ws->groupname)); } else { ws->groupname[0] = 0; } memcpy(ws->session_id, msg->session_id.data, msg->session_id.len); if (msg->ipv4 != NULL) { talloc_free(ws->vinfo.ipv4); if (strcmp(msg->ipv4, "0.0.0.0") == 0) ws->vinfo.ipv4 = NULL; else ws->vinfo.ipv4 = talloc_strdup(ws, msg->ipv4); } if (msg->ipv6 != NULL) { talloc_free(ws->vinfo.ipv6); if (strcmp(msg->ipv6, "::") == 0) ws->vinfo.ipv6 = NULL; else ws->vinfo.ipv6 = talloc_strdup(ws, msg->ipv6); } if (msg->ipv4_local != NULL) { talloc_free(ws->vinfo.ipv4_local); if (strcmp(msg->ipv4_local, "0.0.0.0") == 0) ws->vinfo.ipv4_local = NULL; else ws->vinfo.ipv4_local = talloc_strdup(ws, msg->ipv4_local); } if (msg->ipv6_local != NULL) { talloc_free(ws->vinfo.ipv6_local); if (strcmp(msg->ipv6_local, "::") == 0) ws->vinfo.ipv6_local = NULL; else ws->vinfo.ipv6_local = talloc_strdup(ws, msg->ipv6_local); } /* Read any additional data */ if (msg->ipv4_netmask != NULL) { talloc_free(ws->config->network.ipv4_netmask); ws->config->network.ipv4_netmask = talloc_strdup(ws, msg->ipv4_netmask); } if (msg->ipv4_network != NULL) { talloc_free(ws->config->network.ipv4_network); ws->config->network.ipv4_network = talloc_strdup(ws, msg->ipv4_network); } if (msg->ipv6_network != NULL) { talloc_free(ws->config->network.ipv6_network); ws->config->network.ipv6_network = talloc_strdup(ws, msg->ipv6_network); } if (msg->has_ipv6_prefix) { ws->config->network.ipv6_prefix = msg->ipv6_prefix; } if (msg->has_rx_per_sec) ws->config->rx_per_sec = msg->rx_per_sec; if (msg->has_tx_per_sec) ws->config->tx_per_sec = msg->tx_per_sec; if (msg->has_net_priority) ws->config->net_priority = msg->net_priority; if (msg->has_no_udp && msg->no_udp != 0) ws->perm_config->udp_port = 0; if (msg->xml_config_file) { talloc_free(ws->config->xml_config_file); ws->config->xml_config_file = talloc_strdup(ws, msg->xml_config_file); } /* routes */ ws->routes = talloc_size(ws, msg->n_routes*sizeof(char*)); if (ws->routes != NULL) { ws->routes_size = msg->n_routes; for (i = 0; i < ws->routes_size; i++) { ws->routes[i] = talloc_strdup(ws, msg->routes[i]); /* If a default route is detected */ if (ws->routes[i] != NULL && (strcmp(ws->routes[i], "default") == 0 || strcmp(ws->routes[i], "0.0.0.0/0") == 0)) { /* disable all routes */ ws->routes_size = 0; ws->default_route = 1; break; } } } if (check_if_default_route(ws->routes, ws->routes_size)) ws->default_route = 1; ws->no_routes = talloc_size(ws, msg->n_no_routes*sizeof(char*)); if (ws->no_routes != NULL) { ws->no_routes_size = msg->n_no_routes; for (i = 0; i < ws->no_routes_size; i++) { ws->no_routes[i] = talloc_strdup(ws, msg->no_routes[i]); } } ws->dns = talloc_size(ws, msg->n_dns*sizeof(char*)); if (ws->dns != NULL) { ws->dns_size = msg->n_dns; for (i = 0; i < ws->dns_size; i++) { ws->dns[i] = talloc_strdup(ws, msg->dns[i]); } } ws->nbns = talloc_size(ws, msg->n_nbns*sizeof(char*)); if (ws->nbns != NULL) { ws->nbns_size = msg->n_nbns; for (i = 0; i < ws->nbns_size; i++) { ws->nbns[i] = talloc_strdup(ws, msg->nbns[i]); } } } else { oclog(ws, LOG_ERR, "error in received message"); ret = ERR_AUTH_FAIL; goto cleanup; } break; case AUTH__REP__FAILED: default: if (msg->reply != AUTH__REP__FAILED) oclog(ws, LOG_ERR, "unexpected auth reply %u", (unsigned)msg->reply); ret = ERR_AUTH_FAIL; goto cleanup; } ret = 0; cleanup: auth_reply_msg__free_unpacked(msg, &pa); return ret; }