declare_list(clients);
static int clientcount; /* = 0 */
static int maxBandwidth;
-static bool_t bOpus = true;
+bool_t bOpus = true;
int iCodecAlpha, iCodecBeta;
bool_t bPreferAlpha;
}
-#define OPUS_WARN "<strong>WARNING:</strong> Your client doesn't support the Opus codec the server is using, you won't be able to talk or hear anyone. Please upgrade"
+#define OPUS_WARN_USING "<strong>WARNING:</strong> Your client doesn't support the Opus codec the server is using, you won't be able to talk or hear anyone. Please upgrade your Mumble client."
+#define OPUS_WARN_SWITCHING "<strong>WARNING:</strong> Your client doesn't support the Opus codec the server is switching to, you won't be able to talk or hear anyone. Please upgrade your Mumble client."
void recheckCodecVersions(client_t *connectingClient)
{
client_t *client_itr = NULL;
while (Client_iterate(&client_itr) != NULL) {
codec_itr = NULL;
+ if (client_itr->codec_count == 0 && !client_itr->bOpus)
+ continue;
while (Client_codec_iterate(client_itr, &codec_itr) != NULL) {
found = false;
list_iterate(itr, &codec_list) {
cd->count = 1;
list_add_tail(&cd->node, &codec_list);
}
- users++;
- if (client_itr->bOpus)
- opus++;
}
+ users++;
+ if (client_itr->bOpus)
+ opus++;
}
-
+ if (users == 0)
+ return;
+
enableOpus = ((opus * 100 / users) >= getIntConf(OPUS_THRESHOLD));
list_iterate(itr, &codec_list) {
iCodecAlpha = version;
else
iCodecBeta = version;
- } else if (bOpus == enableOpus) {
- if (connectingClient && !connectingClient->bOpus) {
- char *message;
- uint32_t *tree_id;
- message_t *sendmsg = NULL;
-
- message = malloc(strlen(OPUS_WARN));
- if (!message)
- Log_fatal("Out of memory");
- tree_id = malloc(sizeof(uint32_t));
- if (!tree_id)
- Log_fatal("Out of memory");
- *tree_id = 0;
- sendmsg = Msg_create(TextMessage);
- sendmsg->payload.textMessage->message = message;
- sendmsg->payload.textMessage->n_tree_id = 1;
- sendmsg->payload.textMessage->tree_id = tree_id;
- sprintf(message, OPUS_WARN);
- Client_send_message(connectingClient, sendmsg);
- sendmsg = NULL;
- }
+ } else if (bOpus && enableOpus) {
+ if (connectingClient && !connectingClient->bOpus)
+ Client_textmessage(connectingClient, OPUS_WARN_USING);
return;
}
-
- bOpus = enableOpus;
sendmsg = Msg_create(CodecVersion);
sendmsg->payload.codecVersion->alpha = iCodecAlpha;
sendmsg->payload.codecVersion->beta = iCodecBeta;
sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
+ sendmsg->payload.codecVersion->has_opus = true;
+ sendmsg->payload.codecVersion->opus = enableOpus;
+
Client_send_message_except(NULL, sendmsg);
- Log_info("CELT codec switch 0x%x 0x%x (prefer 0x%x)", iCodecAlpha, iCodecBeta,
- bPreferAlpha ? iCodecAlpha : iCodecBeta);
+ if (enableOpus && !bOpus) {
+ client_itr = NULL;
+ while (Client_iterate(&client_itr) != NULL) {
+ if ((client_itr->authenticated || client_itr == connectingClient) &&
+ !client_itr->bOpus) {
+ Client_textmessage(client_itr, OPUS_WARN_SWITCHING);
+ }
+ }
+ Log_info("OPUS codec %s", bOpus ? "enabled" : "disabled");
+ }
+ bOpus = enableOpus;
}
static int findFreeSessionId()
{
struct dlist *itr, *save;
message_t *sendmsg;
+ bool_t authenticatedLeft = client->authenticated;
if (client->authenticated) {
int leave_id;
if (client->context)
free(client->context);
free(client);
+
+ if (authenticatedLeft)
+ recheckCodecVersions(NULL); /* Can use better codec now? */
}
void Client_close(client_t *client)
client->readBlockedOnWrite = true;
return 0;
}
- else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_ZERO_RETURN) {
+ else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_ZERO_RETURN ||
+ SSLi_get_error(client->ssl, rc) == 0) {
Log_info_client(client, "Connection closed by peer");
- if (!client->shutdown_wait)
- Client_close(client);
+ Client_close(client);
}
else {
if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL) {
- Log_info_client(client,"Error: %s - Closing connection", strerror(errno));
+ if (errno == 0)
+ Log_info_client(client, "Connection closed by peer");
+ else
+ Log_info_client(client,"Error: %s - Closing connection (code %d)",
+ strerror(errno));
}
else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_CONNRESET) {
Log_info_client(client, "Connection reset by peer");
return c;
}
+void Client_textmessage(client_t *client, char *text)
+{
+ char *message;
+ uint32_t *tree_id;
+ message_t *sendmsg = NULL;
+
+ message = malloc(strlen(text) + 1);
+ if (!message)
+ Log_fatal("Out of memory");
+ tree_id = malloc(sizeof(uint32_t));
+ if (!tree_id)
+ Log_fatal("Out of memory");
+ *tree_id = 0;
+ sendmsg = Msg_create(TextMessage);
+ sendmsg->payload.textMessage->message = message;
+ sendmsg->payload.textMessage->n_tree_id = 1;
+ sendmsg->payload.textMessage->tree_id = tree_id;
+ strcpy(message, text);
+ Client_send_message(client, sendmsg);
+}
+
int Client_send_message_except(client_t *client, message_t *msg)
{
Timer_restart(&client->idleTime);
Timer_restart(&client->lastActivity);
+ counter = Pds_get_numval(pdi); /* step past session id */
if ((type >> 5) != UDPVoiceOpus) {
- counter = Pds_get_numval(pdi); /* step past session id */
do {
counter = Pds_next8(pdi);
offset = Pds_skip(pdi, counter & 0x7f);