| 167 | } |
| 168 | |
| 169 | cstream * create_socket(const char * host, uint16_t portnum) { |
| 170 | logc(trace, "Creating socket to connect to: %s:%d", host, portnum); |
| 171 | |
| 172 | #ifdef _WIN32 |
| 173 | WSADATA wsa; |
| 174 | if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) { |
| 175 | logc(err, "%s", "WSAStartup failed"); |
| 176 | return NULL; |
| 177 | } |
| 178 | #endif |
| 179 | |
| 180 | struct addrinfo *result, *rp; |
| 181 | struct addrinfo hints; |
| 182 | memset(&hints, 0, sizeof(struct addrinfo)); |
| 183 | hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ |
| 184 | hints.ai_socktype = SOCK_STREAM; /* Datagram socket */ |
| 185 | hints.ai_flags = 0; |
| 186 | hints.ai_protocol = 0; /* Any protocol */ |
| 187 | |
| 188 | char portstr[6]; |
| 189 | snprintf(portstr, 6, "%d", portnum); |
| 190 | |
| 191 | if (getaddrinfo(host, portstr, &hints, &result) != 0) { |
| 192 | logc(err, "%s%s", "Failed to resolve hostname: ", host); |
| 193 | return NULL; |
| 194 | } |
| 195 | |
| 196 | SOCKET sock; |
| 197 | |
| 198 | for (rp = result; rp != NULL; rp = rp->ai_next) { |
| 199 | sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); |
| 200 | if (sock == -1) { |
| 201 | continue; |
| 202 | } |
| 203 | |
| 204 | if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) { |
| 205 | break; |
| 206 | } |
| 207 | |
| 208 | #ifdef WIN32 |
| 209 | closesocket(sock); |
| 210 | #else |
| 211 | close(sock); |
| 212 | #endif |
| 213 | } |
| 214 | |
| 215 | freeaddrinfo(result); |
| 216 | |
| 217 | if (rp == NULL) { |
| 218 | logc(err, "Failed to connect to %s:%u", host, portnum); |
| 219 | return NULL; |
| 220 | } |
| 221 | |
| 222 | cstream *stream = (cstream *) malloc(sizeof(cstream)); |
| 223 | stream->socket_ = sock; |
| 224 | logc(debug, "%s", "Socket successfully connected"); |
| 225 | return stream; |
| 226 | } |