📄 transaction.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 + -