/* TODO: Clean this up!!! */ int mcast_fence_virt(fence_virt_args_t *args) { ip_list_t ipl; char key[MAX_KEY_LEN]; struct timeval tv; int lfd = -1, key_len = 0, fd, ret; int attempts = 0; uint32_t seqno; /* Initialize NSS; required to do hashing, as silly as that sounds... */ if (NSS_NoDB_Init(NULL) != SECSuccess) { printf("Could not initialize NSS\n"); return 1; } if (args->net.auth != AUTH_NONE || args->net.hash != HASH_NONE) { key_len = read_key_file(args->net.key_file, key, sizeof(key)); if (key_len < 0) { printf("Could not read %s; trying without " "authentication\n", args->net.key_file); args->net.auth = AUTH_NONE; args->net.hash = HASH_NONE; key_len = 0; } } /* Do the real work */ if (ip_build_list(&ipl) < 0) { printf("Error building IP address list\n"); return 1; } attempts = args->timeout * 10 / args->retr_time; do { switch (args->net.auth) { case AUTH_NONE: case AUTH_SHA1: case AUTH_SHA256: case AUTH_SHA512: if (args->net.family == PF_INET) { lfd = ipv4_listen(NULL, args->net.port, 10); } else { lfd = ipv6_listen(NULL, args->net.port, 10); } break; /*case AUTH_X509:*/ /* XXX Setup SSL listener socket here */ default: return 1; } if (lfd < 0) { printf("Failed to listen: %s\n", strerror(errno)); usleep(args->retr_time * 100000); if (--attempts > 0) continue; } } while (0); if (lfd < 0) return -1; gettimeofday(&tv, NULL); seqno = (uint32_t)tv.tv_usec; do { if (send_multicast_packets(&ipl, args, seqno, key, key_len)) { close(lfd); return -1; } switch (args->net.auth) { case AUTH_NONE: case AUTH_SHA1: case AUTH_SHA256: case AUTH_SHA512: fd = tcp_wait_connect(lfd, args->retr_time); if (fd < 0 && (errno == ETIMEDOUT || errno == EINTR)) continue; break; /* case AUTH_X509: ... = ssl_wait_connect... */ break; default: close(lfd); return 1; } break; } while (--attempts); if (lfd >= 0) close(lfd); if (fd < 0) { if (attempts <= 0) { printf("Timed out waiting for response\n"); return 1; } printf("Operation failed: %s\n", strerror(errno)); return -1; } switch (args->net.auth) { case AUTH_NONE: case AUTH_SHA1: case AUTH_SHA256: case AUTH_SHA512: ret = tcp_exchange(fd, args->net.auth, key, key_len, args->timeout); close(fd); return ret; break; /* case AUTH_X509: return ssl_exchange(...); */ default: close(fd); return 1; } close(fd); return 1; }
static int tcp_init(listener_context_t *c, const fence_callbacks_t *cb, config_object_t *config, map_object_t *map, void *priv) { tcp_info *info; int listen_sock, ret; /* Initialize NSS; required to do hashing, as silly as that sounds... */ if (NSS_NoDB_Init(NULL) != SECSuccess) { printf("Could not initialize NSS\n"); return 1; } info = calloc(1, sizeof(*info)); if (!info) return -1; info->priv = priv; info->cb = cb; info->map = map; ret = tcp_config(config, &info->args); if (ret < 0) { perror("tcp_config"); return -1; } else if (ret > 0) { printf("%d errors found during configuration\n",ret); return -1; } if (info->args.auth != AUTH_NONE || info->args.hash != HASH_NONE) { info->key_len = read_key_file(info->args.key_file, info->key, sizeof(info->key)); if (info->key_len < 0) { printf("Could not read %s; operating without " "authentication\n", info->args.key_file); info->args.auth = AUTH_NONE; info->args.hash = HASH_NONE; info->key_len = 0; } } if (info->args.family == PF_INET) { listen_sock = ipv4_listen(info->args.addr, info->args.port, 10); } else { listen_sock = ipv6_listen(info->args.addr, info->args.port, 10); } if (listen_sock < 0) { printf("Could not set up listen socket\n"); free(info); return -1; } info->magic = TCP_MAGIC; info->listen_sock = listen_sock; info->history = history_init(check_history, 10, sizeof(fence_req_t)); *c = (listener_context_t)info; return 0; }