wip client
parent
6f909a752b
commit
31e88525ae
@ -1,5 +1,92 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
#include "io.h"
|
||||||
|
#include "str.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
struct client_ctx {
|
||||||
|
int fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void addrinfo_cleanup(struct addrinfo **ai) {
|
||||||
|
if (*ai)
|
||||||
|
freeaddrinfo(*ai);
|
||||||
|
*ai = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static int
|
||||||
|
|
||||||
|
static int client_init(const struct client_conf *conf, struct client_ctx *ctx) {
|
||||||
|
SB_SCOPED(addr_str);
|
||||||
|
struct addrinfo *ai_res __attribute__((cleanup(addrinfo_cleanup))) = NULL;
|
||||||
|
struct addrinfo *ai;
|
||||||
|
struct addrinfo hints;
|
||||||
|
in_port_t *port;
|
||||||
|
int addrinfo_res;
|
||||||
|
FD_SCOPED(sock_fd);
|
||||||
|
|
||||||
|
if (sb_is_null(addr_str = sb_from_sv(conf->addr)))
|
||||||
|
FAIL("failed to alloc");
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
|
hints.ai_protocol = IPPROTO_UDP;
|
||||||
|
|
||||||
|
if ((addrinfo_res = getaddrinfo(addr_str.ptr, NULL, &hints, &ai_res)))
|
||||||
|
FAIL("failed to resolve name: %s", gai_strerror(addrinfo_res));
|
||||||
|
|
||||||
|
for (ai = ai_res; ai; ai = ai->ai_next) {
|
||||||
|
switch (ai->ai_family) {
|
||||||
|
case AF_INET:
|
||||||
|
port = &((struct sockaddr_in *)ai->ai_addr)->sin_port;
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
port = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_port;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
port = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!port)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
*port = htons(conf->port);
|
||||||
|
|
||||||
|
if ((sock_fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) {
|
||||||
|
LOG_ERR("failed to create socket: %s", strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setsockopt_int(sock_fd, SOL_SOCKET, SO_REUSEADDR, 1)) {
|
||||||
|
LOG_ERR("failed to set SO_REUSEADDR: %s", strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: ping, connect
|
||||||
|
|
||||||
|
printf("res family=%d\n", ai->ai_family);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setsockopt_int(sock_fd, SOL_SOCKET, SO_TIMESTAMP, 1))
|
||||||
|
FAIL("failed to set SO_TIMESTAMP: %s", strerror(errno));
|
||||||
|
|
||||||
|
ctx->fd = FD_RELEASE(&sock_fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int client(const struct client_conf *conf) {
|
int client(const struct client_conf *conf) {
|
||||||
|
struct client_ctx ctx;
|
||||||
|
|
||||||
|
if (client_init(conf, &ctx))
|
||||||
|
FAIL("failed to create client socket");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue