*/
#include <sys/poll.h>
#include <sys/socket.h>
+#include <fcntl.h>
#include <errno.h>
#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
#include "log.h"
#include "list.h"
#include "client.h"
newclient->tcpfd = fd;
memcpy(&newclient->remote_tcp, remote, sizeof(struct sockaddr_in));
- newclient->ssl = SSL_newconnection(newclient->tcpfd, &newclient->SSLready);
+ newclient->ssl = SSLi_newconnection(&newclient->tcpfd, &newclient->SSLready);
if (newclient->ssl == NULL) {
Log_warn("SSL negotiation failed with %s:%d", inet_ntoa(remote->sin_addr),
ntohs(remote->sin_port));
list_del(&client->node);
if (client->ssl)
- SSL_free(client->ssl);
+ SSLi_free(client->ssl);
close(client->tcpfd);
clientcount--;
if (client->release)
void Client_close(client_t *client)
{
- SSL_shutdown(client->ssl);
+ SSLi_shutdown(client->ssl);
client->shutdown_wait = true;
}
}
if (!client->SSLready) {
int rc;
- rc = SSL_nonblockaccept(client->ssl, &client->SSLready);
+ rc = SSLi_nonblockaccept(client->ssl, &client->SSLready);
if (rc < 0) {
Client_free(client);
return -1;
do {
errno = 0;
if (!client->msgsize)
- rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], 6 - client->rxcount);
+ rc = SSLi_read(client->ssl, &client->rxbuf[client->rxcount], 6 - client->rxcount);
else
- rc = SSL_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
+ rc = SSLi_read(client->ssl, &client->rxbuf[client->rxcount], client->msgsize);
if (rc > 0) {
message_t *msg;
client->rxcount += rc;
client->rxcount = client->msgsize = 0;
}
} else /* rc <= 0 */ {
- if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
+ if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_READ) {
return 0;
}
- else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
+ else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_WRITE) {
client->readBlockedOnWrite = true;
return 0;
}
- else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_ZERO_RETURN) {
+ else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_ZERO_RETURN) {
Log_info_client(client, "Connection closed by peer");
if (!client->shutdown_wait)
Client_close(client);
}
else {
- if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL) {
- /* Hmm. This is where we end up when the client closes its connection.
- * Kind of strange...
- */
+ if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL) {
Log_info_client(client, "Connection closed by peer");
}
else {
- Log_info_client(client, "SSL error: %d - Closing connection", SSL_get_error(client->ssl, rc));
+ Log_info_client(client, "SSL error: %d - Closing connection", SSLi_get_error(client->ssl, rc));
}
Client_free(client);
return -1;
}
}
- } while (SSL_pending(client->ssl));
+ } while (SSLi_data_pending(client->ssl));
return 0;
}
Log_debug("Client_write: readBlockedOnWrite == true");
return Client_read(client);
}
- rc = SSL_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
+ rc = SSLi_write(client->ssl, &client->txbuf[client->txcount], client->txsize - client->txcount);
if (rc > 0) {
client->txcount += rc;
if (client->txcount == client->txsize)
client->txsize = client->txcount = 0;
}
else if (rc < 0) {
- if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_READ) {
+ if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_READ) {
client->writeBlockedOnRead = true;
return 0;
}
- else if (SSL_get_error(client->ssl, rc) == SSL_ERROR_WANT_WRITE) {
+ else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_WANT_WRITE) {
return 0;
}
else {
- if (SSL_get_error(client->ssl, rc) == SSL_ERROR_SYSCALL)
+ if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL)
Log_warn("Client_write: Error: %s - Closing connection", strerror(errno));
else
- Log_warn("Client_write: SSL error: %d - Closing connection.", SSL_get_error(client->ssl, rc));
+ Log_warn("Client_write: SSL error: %d - Closing connection.", SSLi_get_error(client->ssl, rc));
Client_free(client);
return -1;
}
}
} /* 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;