Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement sync_tcp_reconnect #101

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/example_bass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ int main(int argc, char *argv[])
double row = bass_get_row(stream);
#ifndef SYNC_PLAYER
if (sync_update(rocket, (int)floor(row), &bass_cb, (void *)&stream))
sync_tcp_connect(rocket, "localhost", SYNC_DEFAULT_PORT);
sync_tcp_reconnect(rocket);
#endif

/* draw */
Expand Down
137 changes: 85 additions & 52 deletions lib/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,41 @@ static inline int xrecv(SOCKET s, void *buf, size_t len, int flags)
static struct Library *socket_base = NULL;
#endif

static SOCKET server_connect(const char *host, unsigned short nport)
static SOCKET sock_connect(struct sockaddr *sa, int sa_len)
{
char greet[128];

SOCKET sock = socket(sa->sa_family, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
return INVALID_SOCKET;

if (connect(sock, sa, sa_len) < 0) {
closesocket(sock);
return INVALID_SOCKET;
}

#ifdef USE_NODELAY
int yes = 1;

/* Try disabling Nagle since we're latency-sensitive, UDP would
* really be more appropriate but that's a much bigger change.
*/
(void) setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&yes, sizeof(yes));
#endif

if (xsend(sock, CLIENT_GREET, strlen(CLIENT_GREET), 0) ||
xrecv(sock, greet, strlen(SERVER_GREET), 0) ||
strncmp(SERVER_GREET, greet, strlen(SERVER_GREET))) {
closesocket(sock);
return INVALID_SOCKET;
}

return sock;
}

static SOCKET server_connect(struct sync_device *d,
const char *host,
unsigned short nport)
{
SOCKET sock = INVALID_SOCKET;
#ifdef USE_GETADDRINFO
Expand Down Expand Up @@ -176,9 +210,13 @@ static SOCKET server_connect(const char *host, unsigned short nport)
return INVALID_SOCKET;

for (curr = addr; curr; curr = curr->ai_next) {
int family = curr->ai_family;
struct sockaddr *sa = curr->ai_addr;
int sa_len = (int)curr->ai_addrlen;
sock = sock_connect(curr->ai_addr, (int)curr->ai_addrlen);
if (sock != INVALID_SOCKET) {
memcpy(&d->server.addr, curr->ai_addr, curr->ai_addrlen);
d->server.addrlen = curr->ai_addrlen;
break;
}
}

#else

Expand All @@ -187,49 +225,19 @@ static SOCKET server_connect(const char *host, unsigned short nport)
return INVALID_SOCKET;

for (ap = he->h_addr_list; *ap; ++ap) {
int family = he->h_addrtype;
struct sockaddr_in sin;
struct sockaddr *sa = (struct sockaddr *)&sin;
int sa_len = sizeof(*sa);

sin.sin_family = he->h_addrtype;
sin.sin_port = htons(nport);
memcpy(&sin.sin_addr, *ap, he->h_length);
memset(&sin.sin_zero, 0, sizeof(sin.sin_zero));

#endif

sock = socket(family, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
continue;

if (connect(sock, sa, sa_len) >= 0) {
char greet[128];

#ifdef USE_NODELAY
int yes = 1;
d->server.sin.sin_family = he->h_addrtype;
d->server.sin.sin_port = htons(nport);
memcpy(&d->server.sin.sin_addr, *ap, he->h_length);
memset(&d->server.sin.sin_zero, 0, sizeof(d->server.sin.sin_zero));

sock = sock_connect((struct sockaddr *)&d->server.sin,
sizeof(struct sockaddr));
if (sock != INVALID_SOCKET)
break;
}

/* Try disabling Nagle since we're latency-sensitive, UDP would
* really be more appropriate but that's a much bigger change.
*/
(void) setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&yes, sizeof(yes));
#endif

if (xsend(sock, CLIENT_GREET, strlen(CLIENT_GREET), 0) ||
xrecv(sock, greet, strlen(SERVER_GREET), 0)) {
closesocket(sock);
sock = INVALID_SOCKET;
continue;
}

if (!strncmp(SERVER_GREET, greet, strlen(SERVER_GREET)))
break;
}

closesocket(sock);
sock = INVALID_SOCKET;
}

#ifdef USE_GETADDRINFO
freeaddrinfo(addr);
#endif
Expand Down Expand Up @@ -475,16 +483,9 @@ static int handle_del_key_cmd(SOCKET sock, struct sync_device *data)
return sync_del_key(data->tracks[track], row);
}

int sync_tcp_connect(struct sync_device *d, const char *host, unsigned short port)
int update_tracks(struct sync_device *d)
{
int i;
if (d->sock != INVALID_SOCKET)
closesocket(d->sock);

d->sock = server_connect(host, port);
if (d->sock == INVALID_SOCKET)
return -1;

for (i = 0; i < (int)d->num_tracks; ++i) {
free(d->tracks[i]->keys);
d->tracks[i]->keys = NULL;
Expand All @@ -501,6 +502,38 @@ int sync_tcp_connect(struct sync_device *d, const char *host, unsigned short por
return 0;
}

int sync_tcp_connect(struct sync_device *d, const char *host, unsigned short port)
{
if (d->sock != INVALID_SOCKET)
closesocket(d->sock);

d->sock = server_connect(d, host, port);
if (d->sock == INVALID_SOCKET)
return -1;

return update_tracks(d);
}

int sync_tcp_reconnect(struct sync_device *d)
{
if (d->sock != INVALID_SOCKET)
closesocket(d->sock);


#ifdef USE_GETADDRINFO
d->sock = sock_connect((struct sockaddr *)&d->server.addr,
d->server.addrlen);
#else
d->sock = sock_connect((struct sockaddr *)&d->server.sin,
sizeof(struct sockaddr));
#endif

if (d->sock == INVALID_SOCKET)
return -1;

return update_tracks(d);
}

int sync_connect(struct sync_device *d, const char *host, unsigned short port)
{
return sync_tcp_connect(d, host, port);
Expand Down
8 changes: 8 additions & 0 deletions lib/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ struct sync_device {
#ifndef SYNC_PLAYER
int row;
SOCKET sock;
struct {
#ifdef USE_GETADDRINFO
struct sockaddr_storage addr;
int addrlen;
#else
struct sockaddr_in sin;
#endif
} server;
#endif
struct sync_io_cb io_cb;
};
Expand Down
1 change: 1 addition & 0 deletions lib/sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ struct sync_cb {
};
#define SYNC_DEFAULT_PORT 1338
int sync_tcp_connect(struct sync_device *, const char *, unsigned short);
int sync_tcp_reconnect(struct sync_device *);
int SYNC_DEPRECATED("use sync_tcp_connect instead") sync_connect(struct sync_device *, const char *, unsigned short);
int sync_update(struct sync_device *, int, struct sync_cb *, void *);
int sync_save_tracks(const struct sync_device *);
Expand Down