1 | 1 | | #include "net.h" |
2 | 2 | | #include <arpa/inet.h> |
3 | 3 | | #include <confuse.h> |
| 4 | + | #include <netdb.h> |
4 | 5 | | #include <sodium.h> |
5 | 6 | | #include <stdint.h> |
6 | 7 | | #include <stdlib.h> |
| skipped 140 lines |
147 | 148 | | const char *repository) |
148 | 149 | | { |
149 | 150 | | int result; |
150 | | - | struct sockaddr_in servaddr; |
| 151 | + | |
| 152 | + | struct addrinfo hints, *res, *p; |
151 | 153 | | cfg_t *server_cfg; |
152 | | - | const char *addr; |
153 | | - | int port; |
| 154 | + | const char *addr, *port; |
154 | 155 | | const char *serverpkstr, *pkstr, *skstr; |
155 | 156 | | uint32_t msgsize; |
156 | 157 | | |
| skipped 32 lines |
189 | 190 | | return -1; |
190 | 191 | | } |
191 | 192 | | |
192 | | - | // socket create and verification |
193 | | - | con->sockfd = socket(AF_INET, SOCK_STREAM, 0); |
194 | | - | if (con->sockfd == -1) { |
195 | | - | fprintf(stderr, "Could not create socket to connect to server.\n"); |
| 193 | + | // assign IP, PORT |
| 194 | + | addr = cfg_getstr(server_cfg, "addr"); |
| 195 | + | port = cfg_getstr(server_cfg, "port"); |
| 196 | + | |
| 197 | + | // resolve address |
| 198 | + | memset(&hints, 0, sizeof hints); // make sure the struct is empty |
| 199 | + | hints.ai_family = AF_UNSPEC; // don't care IPv4 or IPv6 |
| 200 | + | hints.ai_socktype = SOCK_STREAM; // TCP stream sockets |
| 201 | + | hints.ai_flags = AI_PASSIVE; // fill in my IP for me |
| 202 | + | if ((result = getaddrinfo(addr, port, &hints, &res)) != 0) { |
| 203 | + | fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(result)); |
196 | 204 | | return -1; |
197 | 205 | | } |
198 | 206 | | |
199 | | - | bzero(&servaddr, sizeof(servaddr)); |
| 207 | + | // connect the client socket to server socket |
| 208 | + | // loop through all the results and connect to the first we can |
| 209 | + | for (p = res; p != NULL; p = p->ai_next) { |
| 210 | + | if ((con->sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == |
| 211 | + | -1) { |
| 212 | + | perror("socket"); |
| 213 | + | continue; |
| 214 | + | } |
200 | 215 | | |
201 | | - | // assign IP, PORT |
202 | | - | addr = cfg_getstr(server_cfg, "addr"); |
203 | | - | port = (int)cfg_getint(server_cfg, "port"); |
204 | | - | servaddr.sin_family = AF_INET; |
205 | | - | servaddr.sin_addr.s_addr = inet_addr(addr); |
206 | | - | servaddr.sin_port = htons(port); |
| 216 | + | if (connect(con->sockfd, p->ai_addr, p->ai_addrlen) == -1) { |
| 217 | + | perror("connect"); |
| 218 | + | close(con->sockfd); |
| 219 | + | continue; |
| 220 | + | } |
207 | 221 | | |
208 | | - | // connect the client socket to server socket |
209 | | - | if (connect(con->sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != |
210 | | - | 0) { |
211 | | - | fprintf(stderr, "connection with the server failed...\n"); |
| 222 | + | break; // if we get here, we must have connected successfully |
| 223 | + | } |
| 224 | + | |
| 225 | + | if (p == NULL) { |
212 | 226 | | goto err_connect; |
213 | 227 | | } |
214 | 228 | | |
| skipped 13 lines |
228 | 242 | | goto err_init_type; |
229 | 243 | | } |
230 | 244 | | |
| 245 | + | freeaddrinfo(res); |
| 246 | + | |
231 | 247 | | return 0; |
232 | 248 | | |
233 | 249 | | err_init_type: |
| skipped 1 lines |
235 | 251 | | err_init_recv: |
236 | 252 | | close(con->sockfd); |
237 | 253 | | err_connect: |
| 254 | + | freeaddrinfo(res); |
238 | 255 | | return -1; |
239 | 256 | | } |
240 | 257 | | |
| skipped 35 lines |