+ struct addrinfo hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_socktype = SOCK_STREAM,
+ .ai_protocol = IPPROTO_TCP,
+ .ai_flags = 0,
+ };
+
+ struct addrinfo *res = NULL;
+
+ if(getaddrinfo(host, port, &hints, &res) || !res) {
+ fprintf(stderr, "Cannot resolve %s port %s: %s", host, port, strerror(errno));
+ return false;
+ }
+
+ fd = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP);
+ if(fd < 0) {
+ fprintf(stderr, "Cannot create TCP socket: %s\n", sockstrerror(sockerrno));
+ return false;
+ }
+
+#ifdef HAVE_MINGW
+ unsigned long arg = 0;
+
+ if(ioctlsocket(fd, FIONBIO, &arg) != 0) {
+ fprintf(stderr, "ioctlsocket failed: %s", sockstrerror(sockerrno));
+ }
+#endif
+
+ if(connect(fd, res->ai_addr, res->ai_addrlen) < 0) {
+ fprintf(stderr, "Cannot connect to %s port %s: %s\n", host, port, sockstrerror(sockerrno));
+ return false;
+ }
+
+ freeaddrinfo(res);
+
+ char data[4096];
+ int version;
+
+ if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %s %d", &code, data, &version) != 3 || code != 0) {
+ fprintf(stderr, "Cannot read greeting from control socket: %s\n", sockstrerror(sockerrno));
+ return false;
+ }
+
+ sendline(fd, "%d ^%s %d", ID, controlcookie, TINC_CTL_VERSION_CURRENT);
+
+ if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &version, &pid) != 3 || code != 4 || version != TINC_CTL_VERSION_CURRENT) {
+ fprintf(stderr, "Could not fully establish control socket connection\n");
+ return false;
+ }
+
+ return true;