/** Based on the parameters it receives, this function creates a new entry * in the connections list. All the memory allocation is done here. * Client is inserted at the head of the list. * @param ip IP address * @param mac MAC address * @param token Token * @return Pointer to the client we just created */ t_client * client_list_add(const char *ip, const char *mac, const char *token) { t_client *curclient; curclient = client_get_new(); curclient->ip = safe_strdup(ip); curclient->mac = safe_strdup(mac); curclient->token = safe_strdup(token); curclient->counters.incoming_delta = curclient->counters.outgoing_delta = curclient->counters.incoming = curclient->counters.incoming_history = curclient->counters.outgoing = curclient->counters.outgoing_history = 0; curclient->counters.last_updated = time(NULL); client_list_insert_client(curclient); debug(LOG_INFO, "Added a new client to linked list: IP: %s Token: %s", ip, token); return curclient; }
/* @internal * @brief During gateway restart, connects to the parent process via the internal socket * Downloads from it the active client list */ void get_clients_from_parent(void) { int sock; struct sockaddr_un sa_un; s_config *config = NULL; char linebuffer[MAX_BUF]; int len = 0; char *running1 = NULL; char *running2 = NULL; char *token1 = NULL; char *token2 = NULL; char onechar; char *command = NULL; char *key = NULL; char *value = NULL; t_client *client = NULL; config = config_get_config(); debug(LOG_INFO, "Connecting to parent to download clients"); /* Connect to socket */ sock = socket(AF_UNIX, SOCK_STREAM, 0); /* XXX An attempt to quieten coverity warning about the subsequent connect call: * Coverity says: "sock is apssed to parameter that cannot be negative" * Although connect expects a signed int, coverity probably tells us that it shouldn't * be negative */ if (sock < 0) { debug(LOG_ERR, "Could not open socket (%s) - client list not downloaded", strerror(errno)); return; } memset(&sa_un, 0, sizeof(sa_un)); sa_un.sun_family = AF_UNIX; strncpy(sa_un.sun_path, config->internal_sock, (sizeof(sa_un.sun_path) - 1)); if (connect(sock, (struct sockaddr *)&sa_un, strlen(sa_un.sun_path) + sizeof(sa_un.sun_family))) { debug(LOG_ERR, "Failed to connect to parent (%s) - client list not downloaded", strerror(errno)); close(sock); return; } debug(LOG_INFO, "Connected to parent. Downloading clients"); LOCK_CLIENT_LIST(); command = NULL; memset(linebuffer, 0, sizeof(linebuffer)); len = 0; client = NULL; /* Get line by line */ while (read(sock, &onechar, 1) == 1) { if (onechar == '\n') { /* End of line */ onechar = '\0'; } linebuffer[len++] = onechar; if (!onechar) { /* We have a complete entry in linebuffer - parse it */ debug(LOG_DEBUG, "Received from parent: [%s]", linebuffer); running1 = linebuffer; while ((token1 = strsep(&running1, "|")) != NULL) { if (!command) { /* The first token is the command */ command = token1; } else { /* Token1 has something like "foo=bar" */ running2 = token1; key = value = NULL; while ((token2 = strsep(&running2, "=")) != NULL) { if (!key) { key = token2; } else if (!value) { value = token2; } } } if (strcmp(command, "CLIENT") == 0) { /* This line has info about a client in the client list */ if (NULL == client) { /* Create a new client struct */ client = client_get_new(); } } /* XXX client check to shut up clang... */ if (key && value && client) { if (strcmp(command, "CLIENT") == 0) { /* Assign the key into the appropriate slot in the connection structure */ if (strcmp(key, "ip") == 0) { client->ip = safe_strdup(value); } else if (strcmp(key, "mac") == 0) { client->mac = safe_strdup(value); } else if (strcmp(key, "token") == 0) { client->token = safe_strdup(value); } else if (strcmp(key, "fw_connection_state") == 0) { client->fw_connection_state = atoi(value); } else if (strcmp(key, "fd") == 0) { client->fd = atoi(value); } else if (strcmp(key, "counters_incoming") == 0) { client->counters.incoming_history = (unsigned long long)atoll(value); client->counters.incoming = client->counters.incoming_history; } else if (strcmp(key, "counters_outgoing") == 0) { client->counters.outgoing_history = (unsigned long long)atoll(value); client->counters.outgoing = client->counters.outgoing_history; } else if (strcmp(key, "counters_last_updated") == 0) { client->counters.last_updated = atol(value); } else { debug(LOG_NOTICE, "I don't know how to inherit key [%s] value [%s] from parent", key, value); } } } } /* End of parsing this command */ if (client) { client_list_insert_client(client); } /* Clean up */ command = NULL; memset(linebuffer, 0, sizeof(linebuffer)); len = 0; client = NULL; } } UNLOCK_CLIENT_LIST(); debug(LOG_INFO, "Client list downloaded successfully from parent"); close(sock); }