errno = 0;
if (!client->msgsize)
rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], 6 - client->rxcount);
- else if (client->drainleft > 0)
- rc = SSL_read(client->ssl, client->rxbuf, client->drainleft > BUFSIZE ? BUFSIZE : client->drainleft);
else
rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
if (rc > 0) {
message_t *msg;
- if (client->drainleft > 0)
- client->drainleft -= rc;
- else {
- client->rxcount += rc;
- if (!client->msgsize && client->rxcount >= 6) {
- uint32_t msgLen;
- memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
- client->msgsize = ntohl(msgLen);
- }
- if (client->msgsize > BUFSIZE - 6 && client->drainleft == 0) {
- Log_info_client(client, "Too big message received (%d bytes). Discarding.", client->msgsize);
- client->rxcount = client->msgsize = 0;
- client->drainleft = client->msgsize;
- }
- else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
- msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
- /* pass messsage to handler */
- if (msg)
- Mh_handle_message(client, msg);
- client->rxcount = client->msgsize = 0;
- }
+ client->rxcount += rc;
+ if (!client->msgsize && client->rxcount >= 6) {
+ uint32_t msgLen;
+ memcpy(&msgLen, &client->rxbuf[2], sizeof(uint32_t));
+ client->msgsize = ntohl(msgLen);
+ }
+ if (client->msgsize > BUFSIZE - 6) {
+ /* XXX - figure out how to handle this. A large size here can represent two cases:
+ * 1. A valid size. The only message that is this big is UserState message with a big texture
+ * 2. An invalid size = protocol error, e.g. connecting with a 1.1.x client
+ */
+ Log_warn("Too big message received (%d bytes). Playing safe and disconnecting client %s:%d",
+ client->msgsize, inet_ntoa(client->remote_tcp.sin_addr), ntohs(client->remote_tcp.sin_port));
+ Client_free(client);
+ return -1;
+ /* client->rxcount = client->msgsize = 0; */
+ }
+ else if (client->rxcount == client->msgsize + 6) { /* Got all of the message */
+ msg = Msg_networkToMessage(client->rxbuf, client->msgsize + 6);
+ /* pass messsage to handler */
+ if (msg)
+ Mh_handle_message(client, msg);
+ client->rxcount = client->msgsize = 0;
}
} else /* rc <= 0 */ {
if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
}
}
} while (SSL_pending(client->ssl));
- return 0;
+
+ return 0;
}
int Client_write_fd(int fd)
Log_debug("Queueing message");
} else {
int len;
- memset(client->txbuf, 0, BUFSIZE);
len = Msg_messageToNetwork(msg, client->txbuf);
doAssert(len < BUFSIZE);
}
} /* while */
}
- if (itr == NULL) {
+ if (itr == NULL) { /* Couldn't find this peer among connected clients */
goto out;
}
+ itr->bUDP = true;
+ len -= 4; /* Adjust for crypt header */
msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
switch (msgType) {
case UDPVoiceSpeex:
case UDPVoiceCELTAlpha:
case UDPVoiceCELTBeta:
- // u->bUdp = true;
Client_voiceMsg(itr, buffer, len);
break;
case UDPPing:
Log_debug("Unknown UDP message type from %s port %d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
break;
}
+
out:
return 0;
}
src->context != NULL && dst->context != NULL && /* ...both source and destination has context */
strcmp(src->context, dst->context) == 0) /* ...and the contexts match */
Client_send_udp(dst, data, len);
- else
+ else
Client_send_udp(dst, data, len - poslen);
}
}
c = list_get_entry(itr, client_t, chan_node);
Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
}
- /* Channel links */
- if (!list_empty(&ch->channel_links)) {
- struct dlist *ch_itr;
- list_iterate(ch_itr, &ch->channel_links) {
- channel_t *ch_link;
- ch_link = list_get_entry(ch_itr, channel_t, link_node);
- list_iterate(itr, &ch_link->clients) {
- client_t *c;
- c = list_get_entry(itr, client_t, chan_node);
- Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
- Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
- }
- }
- }
} else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
int i;
channel_t *ch;
/* Channels */
- for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i] != -1; i++) {
+ for (i = 0; i < TARGET_MAX_CHANNELS && vt->channels[i].channel != -1; i++) {
+ buffer[0] = (uint8_t) (type | 1);
Log_debug("Whisper channel %d", vt->channels[i]);
- ch = Chan_fromId(vt->channels[i]);
+ ch = Chan_fromId(vt->channels[i].channel);
if (ch == NULL)
continue;
list_iterate(itr, &ch->clients) {
c = list_get_entry(itr, client_t, chan_node);
Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
}
+ /* Channel links */
+ if (vt->channels[i].linked && !list_empty(&ch->channel_links)) {
+ struct dlist *ch_itr;
+ list_iterate(ch_itr, &ch->channel_links) {
+ channel_t *ch_link;
+ ch_link = list_get_entry(ch_itr, channel_t, link_node);
+ list_iterate(itr, &ch_link->clients) {
+ client_t *c;
+ c = list_get_entry(itr, client_t, chan_node);
+ Log_debug("Linked voice from %s -> %s", ch->name, ch_link->name);
+ Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
+ }
+ }
+ }
+ /* children */
+ if (vt->channels[i].children) {
+ struct dlist chanlist, *ch_itr;
+ init_list_entry(&chanlist);
+ Chan_buildTreeList(ch, &chanlist);
+ list_iterate(ch_itr, &chanlist) {
+ channel_t *sub;
+ sub = list_get_entry(ch_itr, channellist_t, node)->chan;
+ list_iterate(itr, &sub->clients) {
+ client_t *c;
+ c = list_get_entry(itr, client_t, chan_node);
+ Log_debug("Child voice from %s -> %s", ch->name, sub->name);
+ Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
+ }
+ }
+ Chan_freeTreeList(&chanlist);
+ }
}
/* Sessions */
for (i = 0; i < TARGET_MAX_SESSIONS && vt->sessions[i] != -1; i++) {
client_t *c;
+ buffer[0] = (uint8_t) (type | 2);
Log_debug("Whisper session %d", vt->sessions[i]);
while (Client_iterate(&c) != NULL) {
if (c->sessionId == vt->sessions[i]) {
{
uint8_t *buf, *mbuf;
- if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState)) {
+ if (client->remote_udp.sin_port != 0 && CryptState_isValid(&client->cryptState) &&
+ client->bUDP) {
#if defined(__LP64__)
buf = mbuf = malloc(len + 4 + 16);
buf += 4;
free(mbuf);
} else {
message_t *msg;
- buf = malloc(len);
- memcpy(buf, data, len);
- msg = Msg_create(UDPTunnel);
-
- msg->payload.UDPTunnel->packet.data = buf;
- msg->payload.UDPTunnel->packet.len = len;
+ msg = Msg_CreateVoiceMsg(data, len);
Client_send_message(client, msg);
}
return 0;