diff options
author | Alexander Lantsev <aunsane@gmail.com> | 2015-04-24 08:21:28 +0000 |
---|---|---|
committer | Alexander Lantsev <aunsane@gmail.com> | 2015-04-24 08:21:28 +0000 |
commit | 690f5e6d29d1c85c4be72638eb22843964c2f512 (patch) | |
tree | 47c50956fef107bb1004f9389b817cbe3626d919 /plugins/!NotAdopted/VypressChat/libvqproto/link.c | |
parent | e7112d3e58f97fa0630e0afa04e27796cdf3ce38 (diff) |
All non-working stuff moved from trunk
git-svn-id: http://svn.miranda-ng.org/main/trunk@13071 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/!NotAdopted/VypressChat/libvqproto/link.c')
-rw-r--r-- | plugins/!NotAdopted/VypressChat/libvqproto/link.c | 611 |
1 files changed, 0 insertions, 611 deletions
diff --git a/plugins/!NotAdopted/VypressChat/libvqproto/link.c b/plugins/!NotAdopted/VypressChat/libvqproto/link.c deleted file mode 100644 index 876af36d03..0000000000 --- a/plugins/!NotAdopted/VypressChat/libvqproto/link.c +++ /dev/null @@ -1,611 +0,0 @@ -/*
- * libvqproto: Vypress/QChat protocol interface library
- * (c) Saulius Menkevicius 2005
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id: link.c,v 1.14 2005/03/08 17:21:23 bobas Exp $
- */
-
-#include <time.h>
-#include <stdlib.h>
-
-#include "vqproto.h"
-#include "link.h"
-#include "message.h"
-
-/* global data
- */
-#ifndef MEMWATCH
-void * (* vqp_mmi_malloc)(size_t) = NULL;
-void (* vqp_mmi_free)(void *) = NULL;
-#endif
-
-/* static routines
- */
-static __inline unsigned short
-ushort2bcd(unsigned short ushort)
-{
- return (ushort % 10) | (((ushort / 10) % 10) << 4)
- | (((ushort / 100) % 10) << 8) | (((ushort / 1000) % 10) << 12);
-}
-
-static void
-vqp_make_msg_sig(struct vqp_message_struct * msg)
-{
- static unsigned rand_num = 0;
- int i;
-
- /* hash message contents to get some initial random num */
- if(!rand_num) {
- for(i=0; i < msg->content_len; i++)
- rand_num += msg->content[i];
- rand_num %= 211;
- }
-
- /* make sure the rng is seeded correctly */
- srand((unsigned) time(NULL) + rand_num++);
-
- /* generate packet signature */
- for(i=0; i < VQP_LINK_SIG_LEN; i++)
- msg->sig[i] = (unsigned char)('0' + rand() % ('9' - '0' + 1));
-
- /* add '\0' at the end (not truly necessary, but it helps to have
- * asciiz string instead of an unbounded char[]
- */
- msg->sig[VQP_LINK_SIG_LEN] = '\0';
-}
-
-static int
-vqp_is_seen_msg_sig(struct vqp_link_struct * link, char * sig)
-{
- int i;
- for(i = 0; i < VQP_LINK_SEEN_SIGS_NUM; i++)
- if(!memcmp(link->seen_sigs[i], sig, VQP_LINK_SIG_LEN))
- return 1;
- return 0;
-}
-
-static void
-vqp_add_seen_msg_sig(struct vqp_message_struct * msg)
-{
- memcpy(msg->link->seen_sigs[msg->link->seen_sig_inc],
- msg->sig, VQP_LINK_SIG_LEN);
- msg->link->seen_sig_inc = (msg->link->seen_sig_inc + 1)
- % VQP_LINK_SEEN_SIGS_NUM;
-}
-
-static int
-vqp_link_open_setup_udp_multicast(struct vqp_link_struct * link)
-{
- struct ip_mreq mreq;
- const unsigned char opt_loop = 1;
- const unsigned char ttl = 32;
-
- /* set IP_MULTICAST_LOOP to 1, so our host receives
- * the messages we send
- */
- if(setsockopt( link->tx_socket, IPPROTO_IP, IP_MULTICAST_LOOP,
- (void*)&opt_loop, sizeof(opt_loop)
- ) != 0)
- return -1;
-
- /* set IP_MULTICAST_TTL to 32, that is the packets
- * will go through 32 routers before getting scrapped
- */
- if(setsockopt( link->tx_socket, IPPROTO_IP, IP_MULTICAST_TTL,
- (void *)&ttl, sizeof(ttl)
- ) != 0)
- return -1;
-
-
- /* set our group membership */
- mreq.imr_multiaddr.s_addr = htonl(link->conndata.udp.multicast_address);
- mreq.imr_interface.s_addr = INADDR_ANY;
- if(setsockopt( link->rx_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
- (void *)&mreq, sizeof(mreq)
- ) != 0)
- return -1;
-
- return 0;
-}
-
-static int
-vqp_link_open_setup_tx_broadcast(struct vqp_link_struct * link)
-{
- const int sock_opt = 1;
- return setsockopt(
- link->tx_socket, SOL_SOCKET, SO_BROADCAST,
- (void *)&sock_opt, sizeof(sock_opt));
-}
-
-static int
-vqp_link_open_setup_udp(struct vqp_link_struct * link, int * p_error)
-{
- int setup_result;
- const int sockopt_true = 1;
- struct sockaddr_in sin;
-
- /* setup tx socket */
- link->tx_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if(link->tx_socket < 0) {
- if(p_error)
- *p_error = errno;
- return 1;
- }
-
- link->rx_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if(link->rx_socket < 0) {
- if(p_error)
- *p_error = errno;
-
- closesocket(link->tx_socket);
- return 1;
- }
-
- /* on win32 we can setup the socket so we can
- * use multiple clients on the same pc
- */
-#ifdef _WIN32
- setsockopt(
- link->rx_socket, SOL_SOCKET, SO_REUSEADDR,
- (void *)&sockopt_true, sizeof(sockopt_true));
-#endif
-
- /* bind rx socket */
- sin.sin_family = PF_INET;
- sin.sin_addr.s_addr = htonl(link->conndata.udp.local_address
- ? link->conndata.udp.local_address
- : INADDR_ANY);
- sin.sin_port = htons(link->port);
- if(bind(link->rx_socket, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
- if(p_error)
- *p_error = errno;
-
- closesocket(link->rx_socket);
- closesocket(link->tx_socket);
- return 1;
- }
-
- link->tx_socket = link->rx_socket;
-
- /* setup sockets for multicast or broadcast service
- */
- setup_result = (link->options & VQP_PROTOCOL_OPT_MULTICAST)
- ? vqp_link_open_setup_udp_multicast(link)
- : vqp_link_open_setup_tx_broadcast(link);
-
- if(setup_result < 0) {
- if(p_error)
- *p_error = errno;
-
- closesocket(link->rx_socket);
- closesocket(link->tx_socket);
- return 1;
- }
-
- /* success */
- return 0;
-}
-
-static int vqp_link_open_setup_ipx(struct vqp_link_struct * link, int * p_error)
-{
- struct sockaddr_ipx six;
-
- /* setup tx socket */
- link->tx_socket = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX);
- if(link->tx_socket < 0) {
- if(p_error)
- *p_error = errno;
- return 1;
- }
-
- if(vqp_link_open_setup_tx_broadcast(link)) {
- if(p_error)
- *p_error = errno;
-
- closesocket(link->tx_socket);
- return 1;
- }
-
- /* setup rx socket */
- link->rx_socket = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX);
- if(link->rx_socket < 0) {
- if(p_error)
- *p_error = errno;
- closesocket(link->rx_socket);
- return 1;
- }
-
- /* bind rx socket */
- memset(&six, 0, sizeof(six));
- six.sa_family = AF_IPX;
- six.sa_socket = htons(ushort2bcd(link->port));
-
- if(bind(link->rx_socket, (struct sockaddr *)&six, sizeof(six))) {
- if(p_error)
- *p_error = errno;
-
- closesocket(link->rx_socket);
- closesocket(link->tx_socket);
- return 1;
- }
-
- /* save node and network number */
- memcpy(link->conndata.ipx.netnum, six.sa_netnum, 4);
- memcpy(link->conndata.ipx.nodenum, six.sa_nodenum, 6);
-
- /* success */
- return 0;
-}
-
-/* exported routines
- */
-void vqp_init(
- void * (* mmi_malloc_func)(size_t),
- void (* mmi_free_func)(void *))
-{
-#ifndef MEMWATCH
- if(mmi_malloc_func)
- vqp_mmi_malloc = mmi_malloc_func;
- else vqp_mmi_malloc = malloc;
-
- if(mmi_free_func)
- vqp_mmi_free = mmi_free_func;
- else vqp_mmi_free = free;
-#endif
-}
-
-void vqp_uninit()
-{
-}
-
-vqp_link_t vqp_link_open(
- enum vqp_protocol_type protocol,
- enum vqp_protocol_options options,
- enum vqp_protocol_connection connection,
- unsigned long local_address,
- unsigned long * p_broadcast_addresses, /* 0UL terminated list */
- unsigned long multicast_address,
- unsigned short port,
- int * p_error)
-{
- struct vqp_link_struct * link;
-
- /* alloc and init link struct */
- link = vqp_mmi_malloc(sizeof(struct vqp_link_struct));
- if(!link) {
- if(p_error) *p_error = ENOMEM;
- return NULL;
- }
-
- link->rx_socket = 0;
- link->tx_socket = 0;
- link->protocol = protocol;
- link->options = options;
- link->connection = connection;
- link->port = port ? port: 8167;
- link->seen_sig_inc = 0;
- memset(link->seen_sigs, 0, VQP_LINK_SEEN_SIGS_NUM * VQP_LINK_SIG_LEN);
-
- if(connection == VQP_PROTOCOL_CONN_UDP) {
- /* UDP
- */
- link->conndata.udp.local_address = local_address;
- link->conndata.udp.multicast_address = multicast_address;
- link->conndata.udp.p_broadcast_addresses = NULL;
-
- if(vqp_link_open_setup_udp(link, p_error)) {
- vqp_mmi_free(link);
- return NULL;
- }
-
- /* setup broadcast masks lists
- */
- if(!(link->options & VQP_PROTOCOL_OPT_MULTICAST)) {
- /* standard broadcast
- */
- int i;
- for(i = 0; p_broadcast_addresses[i]; i++) /* nothing */ ;
-
- if(!i) {
- /* no broadcast addresses defined:
- * use 255.255.255.255 */
- link->conndata.udp.p_broadcast_addresses
- = vqp_mmi_malloc(sizeof(unsigned long) * 2);
-
- if(!link->conndata.udp.p_broadcast_addresses) {
- vqp_mmi_free(link);
- if(p_error)
- *p_error = ENOMEM;
-
- closesocket(link->rx_socket);
- closesocket(link->tx_socket);
- return NULL;
- }
-
- link->conndata.udp.p_broadcast_addresses[0] = 0xffffffffUL;
- link->conndata.udp.p_broadcast_addresses[1] = 0UL;
- } else {
- /* copy broadcast addresses */
- size_t listsz = sizeof(unsigned long) * (i + 1);
- link->conndata.udp.p_broadcast_addresses = vqp_mmi_malloc(listsz);
-
- if(link->conndata.udp.p_broadcast_addresses == NULL) {
- vqp_mmi_free(link);
- if(p_error)
- *p_error = ENOMEM;
-
- closesocket(link->rx_socket);
- closesocket(link->tx_socket);
- return NULL;
- }
- memcpy(link->conndata.udp.p_broadcast_addresses,
- p_broadcast_addresses, listsz);
- }
- }
- }
- else {
- /* IPX
- */
- if(vqp_link_open_setup_ipx(link, p_error)) {
- vqp_mmi_free(link);
- return NULL;
- }
- }
-
- return (vqp_link_t)link;
-}
-
-int vqp_link_close(vqp_link_t vqlink)
-{
- struct vqp_link_struct * link = P_VQP_LINK_STRUCT(vqlink);
-
- closesocket(link->tx_socket);
- closesocket(link->rx_socket);
-
- if(link->connection == VQP_PROTOCOL_CONN_UDP && link->conndata.udp.p_broadcast_addresses)
- vqp_mmi_free(link->conndata.udp.p_broadcast_addresses);
-
- vqp_mmi_free(link);
-
- return 0;
-}
-
-int vqp_link_rx_socket(vqp_link_t link)
-{
- return P_VQP_LINK_STRUCT(link)->rx_socket;
-}
-
-enum vqp_protocol_type
-vqp_link_protocol(vqp_link_t link)
-{
- return P_VQP_LINK_STRUCT(link)->protocol;
-}
-
-int vqp_link_send(vqp_msg_t vqmsg)
-{
- struct vqp_message_struct * msg = P_VQP_MESSAGE_STRUCT(vqmsg);
- char * packet;
- size_t packet_len;
-
- /* check that the message contains something */
- if(msg->content_len == 0)
- return EINVAL;
-
- /* check that we have the correct msg dst addr (if specified)
- */
-
- if(msg->link->protocol == VQP_PROTOCOL_VYPRESSCHAT) {
- /* assign & register unique packet id for the message */
- vqp_make_msg_sig(msg);
- vqp_add_seen_msg_sig(msg);
-
- /* alloc real packet contents with signature */
- packet_len = 1 + VQP_LINK_SIG_LEN + msg->content_len;
- packet = vqp_mmi_malloc(packet_len);
- if(!packet)
- return ENOMEM;
-
- /* fill packet contents in */
- packet[0] = 'X'; /* vypress chat packet */
- memcpy(packet + 1, msg->sig, VQP_LINK_SIG_LEN);
- memcpy(packet + 1 + VQP_LINK_SIG_LEN,
- msg->content, msg->content_len);
- } else {
- /* there's no packet sig to add for quickchat packets */
- packet = msg->content;
- packet_len = msg->content_len;
- }
-
- if(msg->link->connection == VQP_PROTOCOL_CONN_UDP) {
- /* IP/UDP transport
- */
- struct sockaddr_in sin;
-
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = PF_INET;
- sin.sin_port = htons(msg->link->port);
-
- /* send message to all the netmasks/multicasts specified */
- if(!vqp_addr_is_nil(&msg->dst_addr)) {
- /* send packet directly to specified address
- */
- sin.sin_addr.s_addr = htonl(msg->dst_addr.node.ip);
- sendto(msg->link->tx_socket, packet, packet_len, 0,
- (struct sockaddr *)&sin, sizeof(sin));
- }
- else if(msg->link->protocol == VQP_PROTOCOL_VYPRESSCHAT
- && (msg->link->options & VQP_PROTOCOL_OPT_MULTICAST))
- {
- /* send packet to multicast group
- */
- sin.sin_addr.s_addr = htonl(msg->link->conndata.udp.multicast_address);
- sendto(msg->link->tx_socket, packet, packet_len, 0,
- (struct sockaddr *)&sin, sizeof(sin));
- }
- else {
- /* send packet to multiple broadcast addresses
- */
- int n;
- for(n = 0; msg->link->conndata.udp.p_broadcast_addresses[n] != 0; n++) {
- sin.sin_addr.s_addr = htonl(
- msg->link->conndata.udp.p_broadcast_addresses[n]);
-
- sendto(msg->link->tx_socket, packet, packet_len, 0,
- (struct sockaddr *)&sin, sizeof(sin));
- }
- }
- }
- else if(msg->link->connection == VQP_PROTOCOL_CONN_IPX) {
- /* IPX transport
- */
- struct sockaddr_ipx six;
-
- memset(&six, 0, sizeof(six));
- six.sa_family = AF_IPX;
- six.sa_socket = htons(ushort2bcd(msg->link->port));
-
- if(!vqp_addr_is_nil(&msg->dst_addr)) {
- /* send packet to specified address
- */
- memcpy(six.sa_netnum, msg->link->conndata.ipx.netnum, 4);
- memcpy(six.sa_nodenum, msg->dst_addr.node.ipx, 6);
- }
- else {
- /* send packet to broadcast
- */
- memset(six.sa_netnum, 0, 4);
- memset(six.sa_nodenum, 0xff, 6);
- }
-
- sendto( msg->link->tx_socket, packet, packet_len, 0,
- (struct sockaddr *)&six, sizeof(six));
- }
-
- /* free packet data */
- if(packet != msg->content)
- vqp_mmi_free(packet);
-
- return 0; /* packet sent ok */
-}
-
-int vqp_link_recv(vqp_link_t vqlink, vqp_msg_t * p_in_msg)
-{
- struct vqp_link_struct * link = P_VQP_LINK_STRUCT(vqlink);
- struct vqp_message_struct * msg;
- struct sockaddr_in sin;
- struct sockaddr_ipx six;
- socklen_t sa_len;
- char * buf;
- ssize_t buf_data_len;
-
- /* receive the msg */
- buf = vqp_mmi_malloc(VQP_MAX_PACKET_SIZE);
-
- if(link->connection == VQP_PROTOCOL_CONN_UDP) {
- sa_len = sizeof(sin);
- buf_data_len = recvfrom(
- link->rx_socket, (void*)buf, VQP_MAX_PACKET_SIZE, 0,
- (struct sockaddr *) &sin, &sa_len);
- } else {
- sa_len = sizeof(six);
- buf_data_len = recvfrom(
- link->rx_socket, (void *)buf, VQP_MAX_PACKET_SIZE, 0,
- (struct sockaddr *) &six, &sa_len);
- }
-
- if(buf_data_len <= 1) {
- vqp_mmi_free(buf);
- return errno;
- }
-
- if(link->protocol == VQP_PROTOCOL_VYPRESSCHAT) {
- /* check that the packets begins with 'X' and contains
- * a signature */
- if(buf[0] != 'X' || buf_data_len < (1 + VQP_LINK_SIG_LEN + 1)) {
- vqp_mmi_free(buf);
- return 1;
- }
-
- /* check that the signature is not already seen */
- if(vqp_is_seen_msg_sig(link, buf + 1)) {
- vqp_mmi_free(buf);
- return 1;
- }
- }
-
- /* alloc message */
- msg = vqp_mmi_malloc(sizeof(struct vqp_message_struct));
- if(!msg) return 1;
-
- msg->link = link;
- msg->src_addr.conn = link->connection;
- if(link->connection == VQP_PROTOCOL_CONN_UDP) {
- msg->src_addr.node.ip = ntohl(sin.sin_addr.s_addr);
- } else {
- memcpy(msg->src_addr.node.ipx, six.sa_nodenum, 6);
- }
-
- /* copy contents */
- msg->content_len = (link->protocol == VQP_PROTOCOL_VYPRESSCHAT)
- ? buf_data_len - 1 - VQP_LINK_SIG_LEN
- : buf_data_len;
-
- msg->content = vqp_mmi_malloc(msg->content_len);
- if(!msg->content) {
- vqp_mmi_free(buf);
- vqp_mmi_free(msg);
- return 1;
- }
-
- if(link->protocol == VQP_PROTOCOL_VYPRESSCHAT) {
- /* copy signature */
- memcpy(msg->sig, buf + 1, VQP_LINK_SIG_LEN);
- msg->sig[VQP_LINK_SIG_LEN] = '\0';
-
- /* copy contents */
- memcpy(msg->content, buf + 1 + VQP_LINK_SIG_LEN, msg->content_len);
- } else {
- memcpy(msg->content, buf, msg->content_len);
- }
-
- /* free packet buffer */
- vqp_mmi_free(buf);
-
- /* return the msg */
- *p_in_msg = msg;
- return 0;
-}
-
-void vqp_addr_nil(vqp_link_t link, vqp_addr_t * p_addr)
-{
- p_addr->conn = P_VQP_LINK_STRUCT(link)->connection;
- memset(&p_addr->node, 0, sizeof(union vqp_addr_node_union));
-}
-
-int vqp_addr_is_nil(vqp_addr_t * p_addr)
-{
- int is_nil;
-
- if(p_addr->conn == VQP_PROTOCOL_CONN_UDP) {
- is_nil = (p_addr->node.ip == 0);
- } else {
- char nil_ipx[6] = { 0, 0, 0, 0, 0, 0 };
- is_nil = memcmp(nil_ipx, p_addr->node.ipx, 6) == 0;
- }
- return is_nil;
-}
-
|