mirror of
https://github.com/owntone/owntone-server.git
synced 2025-04-15 16:48:22 -04:00
[spotify] Make sure failed AP's are avoided on next connection attempt
This commit is contained in:
parent
f27eac8341
commit
03d05ea828
@ -188,8 +188,10 @@ file_select(uint8_t *out, size_t out_len, Track *track, enum sp_bitrates bitrate
|
|||||||
|
|
||||||
/* --------------------------- Connection handling -------------------------- */
|
/* --------------------------- Connection handling -------------------------- */
|
||||||
|
|
||||||
|
// Connects to access point resolver and selects the first access point (unless
|
||||||
|
// it matches "avoid", i.e. an access point that previously failed)
|
||||||
static int
|
static int
|
||||||
ap_resolve(char **address, unsigned short *port)
|
ap_resolve(char **address, unsigned short *port, const char *avoid)
|
||||||
{
|
{
|
||||||
char *body;
|
char *body;
|
||||||
json_object *jresponse = NULL;
|
json_object *jresponse = NULL;
|
||||||
@ -199,6 +201,7 @@ ap_resolve(char **address, unsigned short *port)
|
|||||||
char *ap_port;
|
char *ap_port;
|
||||||
int ap_num;
|
int ap_num;
|
||||||
int ret;
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
free(*address);
|
free(*address);
|
||||||
*address = NULL;
|
*address = NULL;
|
||||||
@ -215,12 +218,22 @@ ap_resolve(char **address, unsigned short *port)
|
|||||||
RETURN_ERROR(SP_ERR_NOCONNECTION, "Unexpected reply from access point resolver");
|
RETURN_ERROR(SP_ERR_NOCONNECTION, "Unexpected reply from access point resolver");
|
||||||
|
|
||||||
ap_num = json_object_array_length(ap_list);
|
ap_num = json_object_array_length(ap_list);
|
||||||
ap = json_object_array_get_idx(ap_list, rand() % ap_num);
|
|
||||||
|
for (i = 0; i < ap_num; i++)
|
||||||
|
{
|
||||||
|
ap = json_object_array_get_idx(ap_list, i);
|
||||||
if (! (ap && json_object_get_type(ap) == json_type_string))
|
if (! (ap && json_object_get_type(ap) == json_type_string))
|
||||||
RETURN_ERROR(SP_ERR_NOCONNECTION, "Unexpected reply from access point resolver");
|
RETURN_ERROR(SP_ERR_NOCONNECTION, "Unexpected reply from access point resolver");
|
||||||
|
|
||||||
ap_address = strdup(json_object_get_string(ap));
|
if (avoid && strncmp(avoid, json_object_get_string(ap), strlen(avoid)) == 0)
|
||||||
|
continue; // This AP has failed on us previously, so avoid
|
||||||
|
|
||||||
|
ap_address = strdup(json_object_get_string(ap));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ap_address)
|
||||||
|
RETURN_ERROR(SP_ERR_NOCONNECTION, "Unexpected reply from access point resolver, no suitable access point");
|
||||||
if (! (ap_port = strchr(ap_address, ':')))
|
if (! (ap_port = strchr(ap_address, ':')))
|
||||||
RETURN_ERROR(SP_ERR_NOCONNECTION, "Unexpected reply from access point resolver, missing port");
|
RETURN_ERROR(SP_ERR_NOCONNECTION, "Unexpected reply from access point resolver, missing port");
|
||||||
*ap_port = '\0';
|
*ap_port = '\0';
|
||||||
@ -285,14 +298,14 @@ connection_idle_cb(int fd, short what, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
connection_make(struct sp_connection *conn, struct sp_conn_callbacks *cb, void *response_cb_arg)
|
connection_make(struct sp_connection *conn, const char *ap_avoid, struct sp_conn_callbacks *cb, void *response_cb_arg)
|
||||||
{
|
{
|
||||||
int response_fd;
|
int response_fd;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!conn->ap_address || !conn->ap_port)
|
if (!conn->ap_address || !conn->ap_port)
|
||||||
{
|
{
|
||||||
ret = ap_resolve(&conn->ap_address, &conn->ap_port);
|
ret = ap_resolve(&conn->ap_address, &conn->ap_port, ap_avoid);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
RETURN_ERROR(ret, sp_errmsg);
|
RETURN_ERROR(ret, sp_errmsg);
|
||||||
}
|
}
|
||||||
@ -330,7 +343,7 @@ connection_make(struct sp_connection *conn, struct sp_conn_callbacks *cb, void *
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum sp_error
|
enum sp_error
|
||||||
ap_connect(struct sp_connection *conn, enum sp_msg_type type, time_t *cooldown_ts, struct sp_conn_callbacks *cb, void *cb_arg)
|
ap_connect(struct sp_connection *conn, enum sp_msg_type type, time_t *cooldown_ts, const char *ap_avoid, struct sp_conn_callbacks *cb, void *cb_arg)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
time_t now;
|
time_t now;
|
||||||
@ -348,7 +361,7 @@ ap_connect(struct sp_connection *conn, enum sp_msg_type type, time_t *cooldown_t
|
|||||||
else
|
else
|
||||||
RETURN_ERROR(SP_ERR_NOCONNECTION, "Cannot connect to access point, cooldown after disconnect is in effect");
|
RETURN_ERROR(SP_ERR_NOCONNECTION, "Cannot connect to access point, cooldown after disconnect is in effect");
|
||||||
|
|
||||||
ret = connection_make(conn, cb, cb_arg);
|
ret = connection_make(conn, ap_avoid, cb, cb_arg);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
RETURN_ERROR(ret, sp_errmsg);
|
RETURN_ERROR(ret, sp_errmsg);
|
||||||
}
|
}
|
||||||
@ -363,6 +376,12 @@ ap_connect(struct sp_connection *conn, enum sp_msg_type type, time_t *cooldown_t
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
ap_address_get(struct sp_connection *conn)
|
||||||
|
{
|
||||||
|
return conn->ap_address;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------ Raw packets ------------------------------- */
|
/* ------------------------------ Raw packets ------------------------------- */
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
|
@ -2,7 +2,10 @@ void
|
|||||||
ap_disconnect(struct sp_connection *conn);
|
ap_disconnect(struct sp_connection *conn);
|
||||||
|
|
||||||
enum sp_error
|
enum sp_error
|
||||||
ap_connect(struct sp_connection *conn, enum sp_msg_type type, time_t *cooldown_ts, struct sp_conn_callbacks *cb, void *cb_arg);
|
ap_connect(struct sp_connection *conn, enum sp_msg_type type, time_t *cooldown_ts, const char *ap_address, struct sp_conn_callbacks *cb, void *cb_arg);
|
||||||
|
|
||||||
|
const char *
|
||||||
|
ap_address_get(struct sp_connection *conn);
|
||||||
|
|
||||||
enum sp_error
|
enum sp_error
|
||||||
response_read(struct sp_session *session);
|
response_read(struct sp_session *session);
|
||||||
|
@ -322,6 +322,9 @@ struct sp_session
|
|||||||
struct sp_connection conn;
|
struct sp_connection conn;
|
||||||
time_t cooldown_ts;
|
time_t cooldown_ts;
|
||||||
|
|
||||||
|
// Address of an access point we want to avoid due to previous failure
|
||||||
|
char *ap_avoid;
|
||||||
|
|
||||||
bool is_logged_in;
|
bool is_logged_in;
|
||||||
struct sp_credentials credentials;
|
struct sp_credentials credentials;
|
||||||
char country[3]; // Incl null term
|
char country[3]; // Incl null term
|
||||||
|
@ -96,6 +96,8 @@ session_free(struct sp_session *session)
|
|||||||
ap_disconnect(&session->conn);
|
ap_disconnect(&session->conn);
|
||||||
|
|
||||||
event_free(session->continue_ev);
|
event_free(session->continue_ev);
|
||||||
|
|
||||||
|
free(session->ap_avoid);
|
||||||
free(session);
|
free(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,12 +250,16 @@ session_retry(struct sp_session *session)
|
|||||||
{
|
{
|
||||||
struct sp_channel *channel = session->now_streaming_channel;
|
struct sp_channel *channel = session->now_streaming_channel;
|
||||||
enum sp_msg_type type = session->msg_type_last;
|
enum sp_msg_type type = session->msg_type_last;
|
||||||
|
const char *ap_address = ap_address_get(&session->conn);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
sp_cb.logmsg("Retrying after disconnect (occurred at msg %d)\n", type);
|
sp_cb.logmsg("Retrying after disconnect (occurred at msg %d)\n", type);
|
||||||
|
|
||||||
channel_retry(channel);
|
channel_retry(channel);
|
||||||
|
|
||||||
|
free(session->ap_avoid);
|
||||||
|
session->ap_avoid = strdup(ap_address);
|
||||||
|
|
||||||
ap_disconnect(&session->conn);
|
ap_disconnect(&session->conn);
|
||||||
|
|
||||||
// If we were in the middle of a handshake when disconnected we must restart
|
// If we were in the middle of a handshake when disconnected we must restart
|
||||||
@ -443,7 +449,7 @@ request_make(enum sp_msg_type type, struct sp_session *session)
|
|||||||
// sp_cb.logmsg("Making request %d\n", type);
|
// sp_cb.logmsg("Making request %d\n", type);
|
||||||
|
|
||||||
// Make sure the connection is in a state suitable for sending this message
|
// Make sure the connection is in a state suitable for sending this message
|
||||||
ret = ap_connect(&session->conn, type, &session->cooldown_ts, &cb, session);
|
ret = ap_connect(&session->conn, type, &session->cooldown_ts, session->ap_avoid, &cb, session);
|
||||||
if (ret == SP_OK_WAIT)
|
if (ret == SP_OK_WAIT)
|
||||||
return relogin(type, session); // Can't proceed right now, the handshake needs to complete first
|
return relogin(type, session); // Can't proceed right now, the handshake needs to complete first
|
||||||
else if (ret < 0)
|
else if (ret < 0)
|
||||||
|
@ -180,6 +180,8 @@ tcp_connect(const char *address, unsigned short port)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Connected to %s (port %u)\n", address, port);
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user