⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 transaction.c

📁 big pond WAN connect function
💻 C
字号:
/*
**	BPALogin v2.0 - lightweight portable BIDS2 login client
**	Copyright (c) 1999  Shane Hyde (shyde@trontech.com.au)
** 
**  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., 675 Mass Ave, Cambridge, MA 02139, USA.
**
*/ 

#include <bpalogin.h>

void add_trans_data(struct transaction * t,char *p,int count)
{
	memcpy(t->data+t->length,p,count);
	t->length += count;
}

void add_int2field(struct transaction * t,INT2 v)
{
	add_trans_data(t,(char *)&v,2);
}

void add_int4field(struct transaction * t,INT4 v)
{
	add_trans_data(t,(char *)&v,4);
}

void add_string(struct transaction * t,char *s)
{
	add_int2field(t,htons((INT2)(strlen(s)+4)));
	add_trans_data(t,s,strlen(s));
}

void add_data(struct transaction * t,char *s,int c)
{
	add_int2field(t,htons((INT2)(c+4)));
	add_trans_data(t,s,c);
}

void add_field_string(struct session *s,struct transaction * t,INT2 fn,char * p)
{
    s->debug(1,"Sending parm %d value %s\n",fn,p);

	add_int2field(t,htons(fn));
	add_string(t,p);
}

void add_field_data(struct session *s,struct transaction * t,INT2 fn,char * p,int c)
{
    s->debug(1,"Sending parm %d value %s\n",fn,p);

	add_int2field(t,htons(fn));
	add_data(t,p,c);
}

void add_field_INT2(struct session *s,struct transaction * t,INT2 fn,INT2 v)
{
    s->debug(1,"Sending parm %d value %d\n",fn,v);

	add_int2field(t,htons(fn));
	add_int2field(t,htons(6));
	add_int2field(t,htons(v));
}

void add_field_INT4(struct session *s,struct transaction * t,INT2 fn,INT4 v)
{
	s->debug(1, "Sending parm %d value %d\n",fn,v);

	add_int2field(t,htons(fn));
	add_int2field(t,htons(8));
	add_int4field(t,htonl(v));
}

void start_transaction(struct transaction * t,INT2 msgtype,INT4 sessionid)
{
	t->length = 0;
	memset(t->data,0,1512);
	add_int2field(t,htons(msgtype));
	add_int2field(t,htons(0));
	add_int4field(t,htonl(sessionid));
}

void dump_transaction(struct session * s,struct transaction * t)
{
	int i;
	char * p = t->data;
	i = 0;
	while (i < t->length)
	{
        //s->debug(2,"%d:%02x ", i, (unsigned char)*(p));
		p++;
		i++;
	}

    //s->debug(2,"\n");
}

void dump_sent_transaction(struct session *s,struct transaction * t)
{
    s->debug(2,"Sent transaction:\n");
    //dump_transaction(s, t);
}

void dump_recv_transaction(struct session *s,struct transaction * t)
{
    s->debug(2,"Received transaction:\n");
    //dump_transaction(s, t);
}

void send_transaction(struct session *s,int socket,struct transaction * t)
{
	int r;
	INT2 * lll;

	lll = (INT2 *)(t->data+2);
	*lll = htons((INT2)t->length);

	r = send(socket,(void *)t,t->length,0);
	dump_sent_transaction(s,t);
}

void send_udp_transaction(struct session * s,struct transaction * t)
{
	int r;
	
	INT2 * lll;

	lll = (INT2 *)(t->data+2);
	*lll = htons((INT2)t->length);

	s->fromaddr.sin_port = htons(s->statusport);
	r = sendto(s->listensock,(void *)t,t->length,0,(struct sockaddr *)&s->fromaddr,sizeof(s->fromaddr));
	dump_sent_transaction(s,t);
}

INT2 receive_transaction(struct session *s,int socket,struct transaction * t)
{
	INT2 * v;
	int r = recv(socket,(char *)t,1500,0);

	t->length = r;
	dump_recv_transaction(s,t);

	v = (INT2 *)t;

	return (r>0 ? ntohs(*v): 0);
}

int check_hb_packet(struct session * s,struct transaction * t,int length)
{
	INT2 type;

	type = ntohs(*(INT2 *)t);
	if(type != T_MSG_STATUS_REQ) 
	{
        s->debug(0,"Incorrect transaction type %d",type);
		return 0;
	}

	if(length != 8)
	{
        s->debug(0,"Incorrect transaction length %d",length);
		return 0;
	}
	return 1;
}

INT2 receive_udp_transaction(struct session *s, int socket, struct transaction * t, struct sockaddr_in *addr)
{
	struct timeval timeval;
	fd_set readfds;
	INT2 * v;
	int l = sizeof(struct sockaddr_in);
	int r,i;

    // Simon added for 
    int count = 0;

	//timeval.tv_sec = 420;
	//timeval.tv_usec = 0;

	timeval.tv_sec = 0;
	timeval.tv_usec = 100000;   // Wakeup every 100 ms

	FD_ZERO(&readfds);
	FD_SET(socket, &readfds);

    // Simon ++++++++++++++++++++++++++++++++
    //r = select(socket+1, &readfds, NULL, NULL, &timeval);
    // Wait 4200 * 100ms = 420 seconds = 7 minutes
    while (count++ < 4200)
    {
        if (bpa_isshutdown(s))
			return -1;

        r = select(socket+1, &readfds, NULL, NULL, &timeval);
        if (r == -1)
            break;
        else if (r > 0)
            break;
    }
    // Simon ++++++++++++++++++++++++++++++++++

    // Original process
	if (r == -1)
	{
		return (INT2) 0xfffe;
	}
	else if (!r)
	{
        // Timeout
		return (INT2) 0xffff;
	}
	else
	{
		r = recvfrom(socket, (char *)t, 1500, 0, (struct sockaddr*)addr, &l);
		if (r==-1)
			return (INT2) 0xfffe;

		if (s->lastheartbeat + s->minheartbeat > time(NULL))
		{
        	s->recenthb++;
        	if(s->recenthb > 3)
        	{
                s->debug(0,"Heartbeats arriving too quickly - discarding\n");
				return (INT2)0xfffd;
        	}
		}
		else
        	s->recenthb = 0;

		s->lastheartbeat = time(NULL);
	}

	for (i=0; i<s->tsmcount; i++)
	{
		if (addr->sin_addr.s_addr == s->tsmlist_in[i].sin_addr.s_addr)
			break;
	}

	if (i == s->tsmcount)
	{
        s->debug(0,"Received a heartbeat from unexpected source %s:%d\n", inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
		return (INT2)0xfffd;
	}

	t->length = r;

	dump_recv_transaction(s, t);

	/*
	**  Lets make sure this packet is structured correctly
	*/
	if (!check_hb_packet(s, t, r))
	{
		return (INT2)0xfffd;
	}

	dump_recv_transaction(s, t);

	v = (INT2 *)t;

	return (r>0? ntohs(*v) : 0);
}


char * locate_parm(struct transaction * t,INT2 parm)
{
	char * p = t->data,*pp,*lp,*vp;
	INT2 p1;
	INT2 l;
	int i;

	i = 8;
	p += 8;
	while(i < t->length)
	{
		pp = p;
		lp = p+2;
		vp = p+4;

		l = read_INT2(lp);
		p1 = read_INT2(pp);

		if(parm == p1)
		{
			return vp;
		}
		p += l;
		i += l;
	}
	return NULL;
}

int extract_valueINT2(struct session *s,struct transaction * t,INT2 parm,INT2 *v)
{
	INT2 * pp = (INT2 *)locate_parm(t,parm);
	if(pp)
	{
		*v = read_INT2(pp);
        s->debug(1,"Received parm %d value %d\n",parm,*v);

		return TRUE;
	}
	return FALSE;
}

int extract_valueINT4(struct session *s,struct transaction * t,INT2 parm,INT4 *v)
{
	INT4 * pp = (INT4 *)locate_parm(t,parm);
	if(pp)
	{
		*v = read_INT4(pp);
        s->debug(1,"Received parm %d value %d\n",parm,*v);

		return TRUE;
	}
	return FALSE;
}

int extract_valuestring(struct session *s,struct transaction * t,INT2 parm,char * v)
{
	char * pp = locate_parm(t,parm);
	if(pp)
	{
		INT2 l = read_INT2(pp-2);
		memcpy(v,pp,l-4);
		*(v+l-4) = 0;
        s->debug(1,"Received parm %d value %s\n",parm,v);

		return TRUE;
	}
	return FALSE;
}

INT2 read_INT2(void *pp)
{
#ifdef __i386
	return ntohs(*((INT2*)pp));
#else
	unsigned char * p = (unsigned char *)pp;
	return (((INT2)(*p))<<8) + ((INT2)(*(p+1)));
#endif
}

INT4 read_INT4(void *pp)
{
#ifdef __i386
	return ntohl(*((INT4*)pp));
#else
	unsigned char * p = (unsigned char *)pp;
	return (((INT4)(*p))<<24) + (((INT4)(*(p+1)))<<16) + (((INT4)(*(p+2)))<<8) + (((INT4)(*(p+3))));
#endif
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -