SilcPacketType type,
SilcPacketFlags flags,
unsigned char *data,
- unsigned int data_len,
+ uint32 data_len,
int force_send)
{
void *dst_id = NULL;
void *dst_id,
SilcIdType dst_id_type,
unsigned char *data,
- unsigned int data_len,
+ uint32 data_len,
int force_send)
{
SilcPacketContext packetdata;
SilcCipher cipher = NULL;
SilcHmac hmac = NULL;
unsigned char *dst_id_data = NULL;
- unsigned int dst_id_len = 0;
+ uint32 dst_id_len = 0;
SILC_LOG_DEBUG(("Sending packet, type %d", type));
packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
packetdata.src_id_len + dst_id_len;
packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
- packetdata.rng = server->rng;
+
+ /* Prepare outgoing data buffer for packet sending */
+ silc_packet_send_prepare(sock,
+ SILC_PACKET_HEADER_LEN +
+ packetdata.src_id_len +
+ packetdata.dst_id_len,
+ packetdata.padlen,
+ data_len);
+
+ SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
+
+ packetdata.buffer = sock->outbuf;
+
+ /* Put the data to the buffer */
+ if (data && data_len)
+ silc_buffer_put(sock->outbuf, data, data_len);
+
+ /* Create the outgoing packet */
+ silc_packet_assemble(&packetdata);
+
+ if (idata) {
+ cipher = idata->send_key;
+ hmac = idata->hmac;
+ }
+
+ /* Encrypt the packet */
+ silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len);
+
+ SILC_LOG_HEXDUMP(("Outgoing packet, len %d", sock->outbuf->len),
+ sock->outbuf->data, sock->outbuf->len);
+
+ /* Now actually send the packet */
+ silc_server_packet_send_real(server, sock, force_send);
+
+ if (packetdata.src_id)
+ silc_free(packetdata.src_id);
+ if (packetdata.dst_id)
+ silc_free(packetdata.dst_id);
+}
+
+/* Assembles a new packet to be sent out to network. This doesn't actually
+ send the packet but creates the packet and fills the outgoing data
+ buffer and marks the packet ready to be sent to network. However, If
+ argument force_send is TRUE the packet is sent immediately and not put
+ to queue. Normal case is that the packet is not sent immediately.
+ The source and destination information is sent as argument for this
+ function. */
+
+void silc_server_packet_send_srcdest(SilcServer server,
+ SilcSocketConnection sock,
+ SilcPacketType type,
+ SilcPacketFlags flags,
+ void *src_id,
+ SilcIdType src_id_type,
+ void *dst_id,
+ SilcIdType dst_id_type,
+ unsigned char *data,
+ uint32 data_len,
+ int force_send)
+{
+ SilcPacketContext packetdata;
+ SilcIDListData idata;
+ SilcCipher cipher = NULL;
+ SilcHmac hmac = NULL;
+ unsigned char *dst_id_data = NULL;
+ uint32 dst_id_len = 0;
+ unsigned char *src_id_data = NULL;
+ uint32 src_id_len = 0;
+
+ SILC_LOG_DEBUG(("Sending packet, type %d", type));
+
+ /* Get data used in the packet sending, keys and stuff */
+ idata = (SilcIDListData)sock->user_data;
+
+ if (dst_id) {
+ dst_id_data = silc_id_id2str(dst_id, dst_id_type);
+ dst_id_len = silc_id_get_len(dst_id_type);
+ }
+
+ if (src_id) {
+ src_id_data = silc_id_id2str(src_id, src_id_type);
+ src_id_len = silc_id_get_len(src_id_type);
+ }
+
+ /* Set the packet context pointers */
+ packetdata.type = type;
+ packetdata.flags = flags;
+ packetdata.src_id = src_id_data;
+ packetdata.src_id_len = src_id_len;
+ packetdata.src_id_type = src_id_type;
+ packetdata.dst_id = dst_id_data;
+ packetdata.dst_id_len = dst_id_len;
+ packetdata.dst_id_type = dst_id_type;
+ packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
+ packetdata.src_id_len + dst_id_len;
+ packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
/* Prepare outgoing data buffer for packet sending */
silc_packet_send_prepare(sock,
SilcCipher cipher,
SilcHmac hmac,
unsigned char *data,
- unsigned int data_len,
+ uint32 data_len,
int channel_message,
int force_send)
{
SilcPacketType type,
unsigned char route,
unsigned char *data,
- unsigned int data_len,
+ uint32 data_len,
int force_send)
{
SilcSocketConnection sock = NULL;
SilcServerEntry *routed = NULL;
SilcChannelClientEntry chl;
SilcIDListData idata;
- unsigned int routed_count = 0;
+ uint32 routed_count = 0;
/* This doesn't send channel message packets */
if (type == SILC_PACKET_CHANNEL_MESSAGE)
packetdata.dst_id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
packetdata.dst_id_type = SILC_ID_CHANNEL;
- packetdata.rng = server->rng;
packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
packetdata.src_id_len + packetdata.dst_id_len;
packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
void *sender,
SilcIdType sender_type,
unsigned char *data,
- unsigned int data_len,
+ uint32 data_len,
int force_send)
{
int found = FALSE;
SilcClientEntry client = NULL;
SilcServerEntry *routed = NULL;
SilcChannelClientEntry chl;
- unsigned int routed_count = 0;
+ uint32 routed_count = 0;
SilcIDListData idata;
SILC_LOG_DEBUG(("Relaying packet to channel"));
packetdata.dst_id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
packetdata.dst_id_type = SILC_ID_CHANNEL;
- packetdata.rng = server->rng;
packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
packetdata.src_id_len +
packetdata.dst_id_len));
silc_id_render(client->id, SILC_ID_CLIENT),
sock->hostname, sock->ip));
- /* Send the packet */
- silc_server_packet_send_to_channel_real(server, sock, &packetdata,
- idata->send_key, idata->hmac,
- data, data_len, TRUE,
- force_send);
-
/* We want to make sure that the packet is routed to same router
only once. Mark this route as sent route. */
k = routed_count;
routed[k] = client->router;
routed_count++;
+ /* If the remote connection is router then we'll decrypt the
+ channel message and re-encrypt it with the session key shared
+ between us and the remote router. This is done because the
+ channel keys are cell specific and we have different channel
+ key than the remote router has. */
+ if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
+
+ /* If private key mode is not set then decrypt the packet
+ and re-encrypt it */
+ if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
+ unsigned char *tmp = silc_calloc(data_len, sizeof(*data));
+ memcpy(tmp, data, data_len);
+
+ /* Decrypt the channel message (we don't check the MAC) */
+ if (!silc_channel_message_payload_decrypt(tmp, data_len,
+ channel->channel_key,
+ NULL)) {
+ memset(tmp, 0, data_len);
+ silc_free(tmp);
+ continue;
+ }
+
+ /* Now re-encrypt and send it to the router */
+ silc_server_packet_send_srcdest(server, sock,
+ SILC_PACKET_CHANNEL_MESSAGE, 0,
+ sender, sender_type,
+ channel->id, SILC_ID_CHANNEL,
+ tmp, data_len, force_send);
+
+ /* Free the copy of the channel message */
+ memset(tmp, 0, data_len);
+ silc_free(tmp);
+ } else {
+ /* Private key mode is set, we don't have the channel key, so
+ just re-encrypt the entire packet and send it to the router. */
+ silc_server_packet_send_srcdest(server, sock,
+ SILC_PACKET_CHANNEL_MESSAGE, 0,
+ sender, sender_type,
+ channel->id, SILC_ID_CHANNEL,
+ data, data_len, force_send);
+ }
+ continue;
+ }
+
+ /* Send the packet (to normal server) */
+ silc_server_packet_send_to_channel_real(server, sock, &packetdata,
+ idata->send_key, idata->hmac,
+ data, data_len, TRUE,
+ force_send);
+
continue;
}
SilcPacketType type,
SilcPacketFlags flags,
unsigned char *data,
- unsigned int data_len,
+ uint32 data_len,
int force_send)
{
SilcChannelClientEntry chl;
{
SilcBuffer buffer = packet->buffer;
- /* Send and re-encrypt if private messge key does not exist */
+ /* Re-encrypt and send if private messge key does not exist */
if ((packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) == FALSE) {
silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
silc_server_packet_send_real(server, dst_sock, FALSE);
} else {
- /* Key exist so just send it */
+ /* Key exist so encrypt just header and send it */
silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
+ packet->dst_id_len + packet->padlen);
silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
+
+ /* Encrypt header */
+ silc_packet_encrypt(cipher, hmac, dst_sock->outbuf,
+ SILC_PACKET_HEADER_LEN + packet->src_id_len +
+ packet->dst_id_len + packet->padlen);
+
silc_server_packet_send_real(server, dst_sock, FALSE);
}
}
SilcSocketConnection sock)
{
char *motd;
- int motd_len;
+ uint32 motd_len;
if (server->config && server->config->motd &&
server->config->motd->motd_file) {
SilcSocketConnection sock,
int broadcast,
SilcNotifyType type,
- unsigned int argc, ...)
+ uint32 argc, ...)
{
va_list ap;
SilcBuffer packet;
silc_buffer_free(packet);
}
+/* Sends notify message and gets the arguments from the `args' Argument
+ Payloads. */
+
+void silc_server_send_notify_args(SilcServer server,
+ SilcSocketConnection sock,
+ int broadcast,
+ SilcNotifyType type,
+ uint32 argc,
+ SilcBuffer args)
+{
+ SilcBuffer packet;
+
+ packet = silc_notify_payload_encode_args(type, argc, args);
+ silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY, 0,
+ packet->data, packet->len, FALSE);
+ silc_buffer_free(packet);
+}
+
/* Send CHANNEL_CHANGE notify type. This tells the receiver to replace the
`old_id' with the `new_id'. */
int broadcast,
SilcChannelID *old_id,
SilcChannelID *new_id,
- unsigned int id_len)
+ uint32 id_len)
{
SilcBuffer idp1, idp2;
int broadcast,
SilcClientID *old_id,
SilcClientID *new_id,
- unsigned int id_len)
+ uint32 id_len)
{
SilcBuffer idp1, idp2;
int broadcast,
SilcChannelEntry channel,
SilcClientID *client_id,
- unsigned int client_id_len)
+ uint32 client_id_len)
{
SilcBuffer idp1, idp2;
int broadcast,
SilcChannelEntry channel,
SilcClientID *client_id,
- unsigned int client_id_len)
+ uint32 client_id_len)
{
SilcBuffer idp;
SilcSocketConnection sock,
int broadcast,
SilcChannelEntry channel,
- unsigned int mode_mask,
- SilcClientID *client_id,
- unsigned int client_id_len)
+ uint32 mode_mask,
+ void *id, SilcIdType id_type,
+ uint32 id_len,
+ char *cipher, char *hmac)
{
SilcBuffer idp;
unsigned char mode[4];
- idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
+ idp = silc_id_payload_encode((void *)id, id_type);
SILC_PUT32_MSB(mode_mask, mode);
silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_CMODE_CHANGE,
- 2, idp->data, idp->len,
- mode, 4);
+ 4, idp->data, idp->len,
+ mode, 4,
+ cipher, cipher ? strlen(cipher) : 0,
+ hmac, hmac ? strlen(hmac) : 0);
silc_buffer_free(idp);
}
SilcSocketConnection sock,
int broadcast,
SilcChannelEntry channel,
- unsigned int mode_mask,
+ uint32 mode_mask,
SilcClientID *client_id,
- unsigned int client_id_len,
+ uint32 client_id_len,
SilcClientID *target,
- unsigned int target_len)
+ uint32 target_len)
{
SilcBuffer idp1, idp2;
unsigned char mode[4];
SilcSocketConnection sock,
int broadcast,
SilcClientID *client_id,
- unsigned int client_id_len,
+ uint32 client_id_len,
char *message)
{
SilcBuffer idp;
silc_buffer_free(idp);
}
-/* Sends SERVER_SIGNOFF notify type. This tells that `server_id' server
- has quit SILC network. */
-
-void silc_server_send_notify_server_signoff(SilcServer server,
- SilcSocketConnection sock,
- int broadcast,
- SilcServerID *server_id,
- unsigned int server_id_len)
-{
- SilcBuffer idp;
-
- idp = silc_id_payload_encode((void *)server_id, SILC_ID_SERVER);
- silc_server_send_notify(server, sock, broadcast,
- SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
- 1, idp->data, idp->len);
- silc_buffer_free(idp);
-}
-
/* Sends TOPIC_SET notify type. This tells that `client_id' changed
the `channel's topic to `topic'. The Notify packet is always destined
to the channel. This function is used to send the topic set notifies
int broadcast,
SilcChannelEntry channel,
SilcClientID *client_id,
- unsigned int client_id_len,
+ uint32 client_id_len,
char *topic)
{
SilcBuffer idp;
silc_buffer_free(idp);
}
+/* Send KICKED notify type. This tells that the `client_id' on `channel'
+ was kicked off the channel. The `comment' may indicate the reason
+ for the kicking. This function is used only between server and router
+ traffic. */
+
+void silc_server_send_notify_kicked(SilcServer server,
+ SilcSocketConnection sock,
+ int broadcast,
+ SilcChannelEntry channel,
+ SilcClientID *client_id,
+ uint32 client_id_len,
+ char *comment)
+{
+ SilcBuffer idp;
+
+ idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
+ silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
+ SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_KICKED,
+ comment ? 2 : 1, idp->data, idp->len,
+ comment, comment ? strlen(comment) : 0);
+ silc_buffer_free(idp);
+}
+
+/* Send KILLED notify type. This tells that the `client_id' client was
+ killed from the network. The `comment' may indicate the reason
+ for the killing. */
+
+void silc_server_send_notify_killed(SilcServer server,
+ SilcSocketConnection sock,
+ int broadcast,
+ SilcClientID *client_id,
+ uint32 client_id_len,
+ char *comment)
+{
+ SilcBuffer idp;
+
+ idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
+ silc_server_send_notify_dest(server, sock, broadcast, (void *)client_id,
+ SILC_ID_CLIENT, SILC_NOTIFY_TYPE_KILLED,
+ comment ? 2 : 1, idp->data, idp->len,
+ comment, comment ? strlen(comment) : 0);
+ silc_buffer_free(idp);
+}
+
+/* Sends UMODE_CHANGE notify type. This tells that `client_id' client's
+ user mode in the SILC Network was changed. This function is used to
+ send the packet between routers as broadcast packet. */
+
+void silc_server_send_notify_umode(SilcServer server,
+ SilcSocketConnection sock,
+ int broadcast,
+ SilcClientID *client_id,
+ uint32 client_id_len,
+ uint32 mode_mask)
+{
+ SilcBuffer idp;
+ unsigned char mode[4];
+
+ idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
+ SILC_PUT32_MSB(mode_mask, mode);
+
+ silc_server_send_notify(server, sock, broadcast,
+ SILC_NOTIFY_TYPE_UMODE_CHANGE, 2,
+ idp->data, idp->len,
+ mode, 4);
+ silc_buffer_free(idp);
+}
+
+/* Sends BAN notify type. This tells that ban has been either `add'ed
+ or `del'eted on the `channel. This function is used to send the packet
+ between routers as broadcast packet. */
+
+void silc_server_send_notify_ban(SilcServer server,
+ SilcSocketConnection sock,
+ int broadcast,
+ SilcChannelEntry channel,
+ char *add, char *del)
+{
+ SilcBuffer idp;
+
+ idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
+ silc_server_send_notify(server, sock, broadcast,
+ SILC_NOTIFY_TYPE_BAN, 3,
+ idp->data, idp->len,
+ add, add ? strlen(add) : 0,
+ del, del ? strlen(del) : 0);
+ silc_buffer_free(idp);
+}
+
+/* Sends INVITE notify type. This tells that invite has been either `add'ed
+ or `del'eted on the `channel. The sender of the invite is the `client_id'.
+ This function is used to send the packet between routers as broadcast
+ packet. */
+
+void silc_server_send_notify_invite(SilcServer server,
+ SilcSocketConnection sock,
+ int broadcast,
+ SilcChannelEntry channel,
+ SilcClientID *client_id,
+ uint32 client_id_len,
+ char *add, char *del)
+{
+ SilcBuffer idp, idp2;
+
+ idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
+ idp2 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
+ silc_server_send_notify(server, sock, broadcast,
+ SILC_NOTIFY_TYPE_INVITE, 5,
+ idp->data, idp->len,
+ channel->channel_name, strlen(channel->channel_name),
+ idp2->data, idp2->len,
+ add, add ? strlen(add) : 0,
+ del, del ? strlen(del) : 0);
+ silc_buffer_free(idp);
+ silc_buffer_free(idp2);
+}
+
/* Sends notify message destined to specific entity. */
void silc_server_send_notify_dest(SilcServer server,
void *dest_id,
SilcIdType dest_id_type,
SilcNotifyType type,
- unsigned int argc, ...)
+ uint32 argc, ...)
{
va_list ap;
SilcBuffer packet;
}
/* Sends notify message to a channel. The notify message sent is
- distributed to all clients on the channel. If `router_notify' is TRUE
+ distributed to all clients on the channel. If `route_notify' is TRUE
then the notify may be routed to primary route or to some other routers.
If FALSE it is assured that the notify is sent only locally. If `sender'
is provided then the packet is not sent to that connection since it
SilcChannelEntry channel,
unsigned char route_notify,
SilcNotifyType type,
- unsigned int argc, ...)
+ uint32 argc, ...)
{
va_list ap;
SilcBuffer packet;
silc_buffer_free(packet);
}
-/* Send notify message to all clients the client has joined. It is quaranteed
+/* Send notify message to all channels the client has joined. It is quaranteed
that the message is sent only once to a client (ie. if a client is joined
on two same channel it will receive only one notify message). Also, this
sends only to local clients (locally connected if we are server, and to
- local servers if we are router). */
+ local servers if we are router). If `sender' is provided the packet is
+ not sent to that client at all. */
void silc_server_send_notify_on_channels(SilcServer server,
+ SilcClientEntry sender,
SilcClientEntry client,
SilcNotifyType type,
- unsigned int argc, ...)
+ uint32 argc, ...)
{
int k;
SilcSocketConnection sock = NULL;
SilcPacketContext packetdata;
SilcClientEntry c;
SilcClientEntry *sent_clients = NULL;
- unsigned int sent_clients_count = 0;
+ uint32 sent_clients_count = 0;
SilcServerEntry *routed = NULL;
- unsigned int routed_count = 0;
+ uint32 routed_count = 0;
SilcChannelEntry channel;
SilcChannelClientEntry chl, chl2;
SilcIDListData idata;
SilcBuffer packet;
unsigned char *data;
- unsigned int data_len;
+ uint32 data_len;
int force_send = FALSE;
va_list ap;
packetdata.src_id = silc_id_id2str(server->id, SILC_ID_SERVER);
packetdata.src_id_len = SILC_ID_SERVER_LEN;
packetdata.src_id_type = SILC_ID_SERVER;
- packetdata.rng = server->rng;
silc_list_start(client->channels);
while ((chl = silc_list_get(client->channels)) != SILC_LIST_END) {
while ((chl2 = silc_list_get(channel->user_list)) != SILC_LIST_END) {
c = chl2->client;
+ if (sender && c == sender)
+ continue;
+
/* Check if we have sent the packet to this client already */
for (k = 0; k < sent_clients_count; k++)
if (sent_clients[k] == c)
SilcSocketConnection sock,
int broadcast,
void *id, SilcIdType id_type,
- unsigned int id_len)
+ uint32 id_len)
{
SilcBuffer idp;
int broadcast,
char *channel_name,
void *channel_id,
- unsigned int channel_id_len)
+ uint32 channel_id_len,
+ uint32 mode)
{
SilcBuffer packet;
unsigned char *cid;
- unsigned int name_len = strlen(channel_name);
+ uint32 name_len = strlen(channel_name);
SILC_LOG_DEBUG(("Start"));
if (!cid)
return;
- packet = silc_buffer_alloc(2 + 2 + name_len + channel_id_len);
- silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
- silc_buffer_format(packet,
- SILC_STR_UI_SHORT(name_len),
- SILC_STR_UI_XNSTRING(channel_name, name_len),
- SILC_STR_UI_SHORT(channel_id_len),
- SILC_STR_UI_XNSTRING(cid, channel_id_len),
- SILC_STR_END);
-
+ /* Encode the channel payload */
+ packet = silc_channel_payload_encode(channel_name, name_len,
+ cid, channel_id_len, mode);
silc_server_packet_send(server, sock, SILC_PACKET_NEW_CHANNEL,
broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
{
SilcBuffer packet;
unsigned char *chid;
- unsigned int tmp_len;
+ uint32 tmp_len;
SILC_LOG_DEBUG(("Start"));
void silc_server_send_command(SilcServer server,
SilcSocketConnection sock,
SilcCommand command,
- unsigned int argc, ...)
+ uint32 argc, ...)
{
SilcBuffer packet;
va_list ap;
silc_server_packet_send(server, sock, SILC_PACKET_HEARTBEAT, 0,
NULL, 0, FALSE);
}
+
+/* Generic function to relay packet we've received. This is used to relay
+ packets to a client but generally can be used to other purposes as well. */
+
+void silc_server_relay_packet(SilcServer server,
+ SilcSocketConnection dst_sock,
+ SilcCipher cipher,
+ SilcHmac hmac,
+ SilcPacketContext *packet,
+ int force_send)
+{
+ silc_buffer_push(packet->buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
+ + packet->dst_id_len + packet->padlen);
+
+ silc_packet_send_prepare(dst_sock, 0, 0, packet->buffer->len);
+ silc_buffer_put(dst_sock->outbuf, packet->buffer->data, packet->buffer->len);
+
+ /* Re-encrypt packet */
+ silc_packet_encrypt(cipher, hmac, dst_sock->outbuf, packet->buffer->len);
+
+ /* Send the packet */
+ silc_server_packet_send_real(server, dst_sock, force_send);
+
+ silc_buffer_pull(packet->buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
+ + packet->dst_id_len + packet->padlen);
+}
+
+/* Routine used to send the connection authentication packet. */
+
+void silc_server_send_connection_auth_request(SilcServer server,
+ SilcSocketConnection sock,
+ uint16 conn_type,
+ SilcAuthMethod auth_meth)
+{
+ SilcBuffer packet;
+
+ packet = silc_buffer_alloc(4);
+ silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
+ silc_buffer_format(packet,
+ SILC_STR_UI_SHORT(conn_type),
+ SILC_STR_UI_SHORT(auth_meth),
+ SILC_STR_END);
+
+ silc_server_packet_send(server, sock, SILC_PACKET_CONNECTION_AUTH_REQUEST,
+ 0, packet->data, packet->len, FALSE);
+ silc_buffer_free(packet);
+}