mirror of
https://github.com/samba-team/samba.git
synced 2024-12-28 07:21:54 +03:00
this code has been sitting on one of my box for 3 months.
add wins push replication, better handling of partners, rewrote half of
parser.
I know some parser code need to be changed to better cope with multihomed
machine and groups.
J.F.
(This used to be commit a2d07bc6eb
)
This commit is contained in:
parent
1d79e6b90e
commit
56de6fa470
@ -26,64 +26,85 @@ extern TALLOC_CTX *mem_ctx;
|
||||
/****************************************************************************
|
||||
grow the send buffer if necessary
|
||||
****************************************************************************/
|
||||
static BOOL grow_buffer(struct BUFFER *buffer, int more)
|
||||
BOOL grow_buffer(struct BUFFER *buffer, int more)
|
||||
{
|
||||
char *temp;
|
||||
|
||||
DEBUG(10,("grow_buffer: size is: %d offet is:%d growing by %d\n", buffer->length, buffer->offset, more));
|
||||
|
||||
/* grow by at least 256 bytes */
|
||||
if (more<256)
|
||||
more=256;
|
||||
|
||||
if (buffer->offset+more >= buffer->length) {
|
||||
temp=(char *)talloc_realloc(mem_ctx, buffer->buffer, sizeof(char)* (buffer->length+256) );
|
||||
temp=(char *)talloc_realloc(mem_ctx, buffer->buffer, sizeof(char)* (buffer->length+more) );
|
||||
if (temp==NULL) {
|
||||
DEBUG(0,("grow_buffer: can't grow buffer\n"));
|
||||
return False;
|
||||
}
|
||||
buffer->length+=256;
|
||||
buffer->length+=more;
|
||||
buffer->buffer=temp;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
check if the buffer has that much data
|
||||
****************************************************************************/
|
||||
static BOOL check_buffer(struct BUFFER *buffer, int more)
|
||||
{
|
||||
char *temp;
|
||||
|
||||
DEBUG(10,("check_buffer: size is: %d offet is:%d growing by %d\n", buffer->length, buffer->offset, more));
|
||||
|
||||
if (buffer->offset+more > buffer->length) {
|
||||
DEBUG(10,("check_buffer: buffer smaller than requested, size is: %d needed: %d\n", buffer->length, buffer->offset+more));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
decode a WINS_OWNER struct
|
||||
****************************************************************************/
|
||||
static int decode_wins_owner(char *inbuf, int offset, WINS_OWNER *wins_owner)
|
||||
static void decode_wins_owner(struct BUFFER *inbuf, WINS_OWNER *wins_owner)
|
||||
{
|
||||
wins_owner->address.s_addr=IVAL(inbuf, offset);
|
||||
offset+=4;
|
||||
wins_owner->max_version=((SMB_BIG_UINT)RIVAL(inbuf, offset))<<32;
|
||||
offset+=4;
|
||||
wins_owner->max_version|=RIVAL(inbuf, offset);
|
||||
offset+=4;
|
||||
wins_owner->min_version=((SMB_BIG_UINT)RIVAL(inbuf, offset))<<32;
|
||||
offset+=4;
|
||||
wins_owner->min_version|=RIVAL(inbuf, offset);
|
||||
offset+=4;
|
||||
wins_owner->type=RIVAL(inbuf, offset);
|
||||
offset+=4;
|
||||
if(!check_buffer(inbuf, 24))
|
||||
return;
|
||||
|
||||
wins_owner->address.s_addr=IVAL(inbuf->buffer, inbuf->offset);
|
||||
wins_owner->max_version=((SMB_BIG_UINT)RIVAL(inbuf->buffer, inbuf->offset+4))<<32;
|
||||
wins_owner->max_version|=RIVAL(inbuf->buffer, inbuf->offset+8);
|
||||
wins_owner->min_version=((SMB_BIG_UINT)RIVAL(inbuf->buffer, inbuf->offset+12))<<32;
|
||||
wins_owner->min_version|=RIVAL(inbuf->buffer, inbuf->offset+16);
|
||||
wins_owner->type=RIVAL(inbuf->buffer, inbuf->offset+20);
|
||||
inbuf->offset+=24;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
decode a WINS_NAME struct
|
||||
****************************************************************************/
|
||||
static int decode_wins_name(char *outbuf, int offset, WINS_NAME *wins_name)
|
||||
static void decode_wins_name(struct BUFFER *outbuf, WINS_NAME *wins_name)
|
||||
{
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
wins_name->name_len=RIVAL(outbuf, offset);
|
||||
offset+=4;
|
||||
memcpy(wins_name->name,outbuf+offset, 15);
|
||||
if(!check_buffer(outbuf, 40))
|
||||
return;
|
||||
|
||||
wins_name->name_len=RIVAL(outbuf->buffer, outbuf->offset);
|
||||
outbuf->offset+=4;
|
||||
memcpy(wins_name->name,outbuf->buffer+outbuf->offset, 15);
|
||||
wins_name->name[16]='\0';
|
||||
if((p = strchr(wins_name->name,' ')) != NULL)
|
||||
*p = 0;
|
||||
|
||||
offset+=15;
|
||||
outbuf->offset+=15;
|
||||
|
||||
wins_name->type=(int)outbuf[offset++];
|
||||
wins_name->type=(int)outbuf->buffer[outbuf->offset++];
|
||||
|
||||
/*
|
||||
* fix to bug in WINS replication,
|
||||
@ -94,136 +115,162 @@ static int decode_wins_name(char *outbuf, int offset, WINS_NAME *wins_name)
|
||||
wins_name->type=0x1B;
|
||||
}
|
||||
|
||||
wins_name->empty=RIVAL(outbuf, offset);
|
||||
offset+=4;
|
||||
wins_name->empty=RIVAL(outbuf->buffer, outbuf->offset);
|
||||
outbuf->offset+=4;
|
||||
|
||||
wins_name->name_flag=RIVAL(outbuf, offset);
|
||||
offset+=4;
|
||||
wins_name->group_flag=RIVAL(outbuf, offset);
|
||||
offset+=4;
|
||||
wins_name->id=((SMB_BIG_UINT)RIVAL(outbuf, offset))<<32;
|
||||
offset+=4;
|
||||
wins_name->id|=RIVAL(outbuf, offset);
|
||||
offset+=4;
|
||||
wins_name->name_flag=RIVAL(outbuf->buffer, outbuf->offset);
|
||||
outbuf->offset+=4;
|
||||
wins_name->group_flag=RIVAL(outbuf->buffer, outbuf->offset);
|
||||
outbuf->offset+=4;
|
||||
wins_name->id=((SMB_BIG_UINT)RIVAL(outbuf->buffer, outbuf->offset))<<32;
|
||||
outbuf->offset+=4;
|
||||
wins_name->id|=RIVAL(outbuf->buffer, outbuf->offset);
|
||||
outbuf->offset+=4;
|
||||
|
||||
/* special groups have multiple address */
|
||||
if (wins_name->name_flag & 2) {
|
||||
wins_name->num_ip=IVAL(outbuf, offset);
|
||||
offset+=4;
|
||||
if(!check_buffer(outbuf, 4))
|
||||
return;
|
||||
wins_name->num_ip=IVAL(outbuf->buffer, outbuf->offset);
|
||||
outbuf->offset+=4;
|
||||
}
|
||||
else
|
||||
wins_name->num_ip=1;
|
||||
|
||||
wins_name->owner.s_addr=IVAL(outbuf, offset);
|
||||
offset+=4;
|
||||
if(!check_buffer(outbuf, 4))
|
||||
return;
|
||||
wins_name->owner.s_addr=IVAL(outbuf->buffer, outbuf->offset);
|
||||
outbuf->offset+=4;
|
||||
|
||||
if (wins_name->name_flag & 2) {
|
||||
wins_name->others=(struct in_addr *)talloc(mem_ctx, sizeof(struct in_addr)*wins_name->num_ip);
|
||||
if (wins_name->others==NULL)
|
||||
return offset;
|
||||
return;
|
||||
|
||||
if(!check_buffer(outbuf, 4*wins_name->num_ip))
|
||||
return;
|
||||
for (i=0; i<wins_name->num_ip; i++) {
|
||||
wins_name->others[i].s_addr=IVAL(outbuf, offset);
|
||||
offset+=4;
|
||||
wins_name->others[i].s_addr=IVAL(outbuf->buffer, outbuf->offset);
|
||||
outbuf->offset+=4;
|
||||
}
|
||||
}
|
||||
|
||||
wins_name->foo=RIVAL(outbuf, offset);
|
||||
offset+=4;
|
||||
if(!check_buffer(outbuf, 4))
|
||||
return;
|
||||
wins_name->foo=RIVAL(outbuf->buffer, outbuf->offset);
|
||||
outbuf->offset+=4;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
decode a update notification request
|
||||
****************************************************************************/
|
||||
static void decode_update_notify_request(char *inbuf, UPDATE_NOTIFY_REQUEST *un_rq)
|
||||
static void decode_update_notify_request(struct BUFFER *inbuf, UPDATE_NOTIFY_REQUEST *un_rq)
|
||||
{
|
||||
int i;
|
||||
int offset=4;
|
||||
|
||||
un_rq->partner_count=RIVAL(inbuf, 0);
|
||||
if(!check_buffer(inbuf, 4))
|
||||
return;
|
||||
un_rq->partner_count=RIVAL(inbuf->buffer, inbuf->offset);
|
||||
inbuf->offset+=4;
|
||||
|
||||
un_rq->wins_owner=(WINS_OWNER *)talloc(mem_ctx, un_rq->partner_count*sizeof(WINS_OWNER));
|
||||
if (un_rq->wins_owner==NULL)
|
||||
return;
|
||||
|
||||
for (i=0; i<un_rq->partner_count; i++)
|
||||
offset=decode_wins_owner(inbuf, offset, &un_rq->wins_owner[i]);
|
||||
decode_wins_owner(inbuf, &un_rq->wins_owner[i]);
|
||||
|
||||
un_rq->initiating_wins_server.s_addr=IVAL(inbuf, offset);
|
||||
if(!check_buffer(inbuf, 4))
|
||||
return;
|
||||
un_rq->initiating_wins_server.s_addr=IVAL(inbuf->buffer, inbuf->offset);
|
||||
inbuf->offset+=4;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
decode a send entries request
|
||||
****************************************************************************/
|
||||
static void decode_send_entries_request(char *inbuf, SEND_ENTRIES_REQUEST *se_rq)
|
||||
static void decode_send_entries_request(struct BUFFER *inbuf, SEND_ENTRIES_REQUEST *se_rq)
|
||||
{
|
||||
int offset;
|
||||
offset=decode_wins_owner(inbuf, 0, &se_rq->wins_owner);
|
||||
decode_wins_owner(inbuf, &se_rq->wins_owner);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
decode a send entries reply
|
||||
****************************************************************************/
|
||||
static void decode_send_entries_reply(char *inbuf, SEND_ENTRIES_REPLY *se_rp)
|
||||
static void decode_send_entries_reply(struct BUFFER *inbuf, SEND_ENTRIES_REPLY *se_rp)
|
||||
{
|
||||
int i, offset=4;
|
||||
se_rp->max_names = RIVAL(inbuf, 0);
|
||||
int i;
|
||||
|
||||
if(!check_buffer(inbuf, 4))
|
||||
return;
|
||||
se_rp->max_names = RIVAL(inbuf->buffer, inbuf->offset);
|
||||
inbuf->offset+=4;
|
||||
|
||||
se_rp->wins_name=(WINS_NAME *)talloc(mem_ctx, se_rp->max_names*sizeof(WINS_NAME));
|
||||
if (se_rp->wins_name==NULL)
|
||||
return;
|
||||
|
||||
for (i=0; i<se_rp->max_names; i++)
|
||||
offset = decode_wins_name(inbuf, offset, &se_rp->wins_name[i]);
|
||||
decode_wins_name(inbuf, &se_rp->wins_name[i]);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
decode a add version number map table reply
|
||||
****************************************************************************/
|
||||
static void decode_add_version_number_map_table_reply(char *inbuf, AVMT_REP *avmt_rep)
|
||||
static void decode_add_version_number_map_table_reply(struct BUFFER *inbuf, AVMT_REP *avmt_rep)
|
||||
{
|
||||
int i;
|
||||
int offset=4;
|
||||
|
||||
avmt_rep->partner_count=RIVAL(inbuf, 0);
|
||||
if(!check_buffer(inbuf, 4))
|
||||
return;
|
||||
|
||||
avmt_rep->partner_count=RIVAL(inbuf->buffer, inbuf->offset);
|
||||
inbuf->offset+=4;
|
||||
|
||||
avmt_rep->wins_owner=(WINS_OWNER *)talloc(mem_ctx, avmt_rep->partner_count*sizeof(WINS_OWNER));
|
||||
if (avmt_rep->wins_owner==NULL)
|
||||
return;
|
||||
|
||||
for (i=0; i<avmt_rep->partner_count; i++)
|
||||
offset=decode_wins_owner(inbuf, offset, &avmt_rep->wins_owner[i]);
|
||||
decode_wins_owner(inbuf, &avmt_rep->wins_owner[i]);
|
||||
|
||||
avmt_rep->initiating_wins_server.s_addr=IVAL(inbuf, offset);
|
||||
if(!check_buffer(inbuf, 4))
|
||||
return;
|
||||
avmt_rep->initiating_wins_server.s_addr=IVAL(inbuf->buffer, inbuf->offset);
|
||||
inbuf->offset+=4;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
decode a replicate packet and fill a structure
|
||||
****************************************************************************/
|
||||
static void decode_replicate(char *inbuf, REPLICATE *rep)
|
||||
static void decode_replicate(struct BUFFER *inbuf, REPLICATE *rep)
|
||||
{
|
||||
rep->msg_type = RIVAL(inbuf, 0);
|
||||
if(!check_buffer(inbuf, 4))
|
||||
return;
|
||||
|
||||
rep->msg_type = RIVAL(inbuf->buffer, inbuf->offset);
|
||||
|
||||
inbuf->offset+=4;
|
||||
|
||||
switch (rep->msg_type) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
/* add version number map table reply */
|
||||
decode_add_version_number_map_table_reply(inbuf+4, &rep->avmt_rep);
|
||||
decode_add_version_number_map_table_reply(inbuf, &rep->avmt_rep);
|
||||
break;
|
||||
case 2:
|
||||
/* send entry request */
|
||||
decode_send_entries_request(inbuf+4, &rep->se_rq);
|
||||
decode_send_entries_request(inbuf, &rep->se_rq);
|
||||
break;
|
||||
case 3:
|
||||
/* send entry request */
|
||||
decode_send_entries_reply(inbuf+4, &rep->se_rp);
|
||||
decode_send_entries_reply(inbuf, &rep->se_rp);
|
||||
break;
|
||||
case 4:
|
||||
/* update notification request */
|
||||
decode_update_notify_request(inbuf+4, &rep->un_rq);
|
||||
decode_update_notify_request(inbuf, &rep->un_rq);
|
||||
break;
|
||||
default:
|
||||
DEBUG(0,("decode_replicate: unknown message type:%d\n", rep->msg_type));
|
||||
@ -234,61 +281,75 @@ static void decode_replicate(char *inbuf, REPLICATE *rep)
|
||||
/****************************************************************************
|
||||
read the generic header and fill the struct.
|
||||
****************************************************************************/
|
||||
static void read_generic_header(char *inbuf, generic_header *q)
|
||||
static void read_generic_header(struct BUFFER *inbuf, generic_header *q)
|
||||
{
|
||||
q->data_size = RIVAL(inbuf,0);
|
||||
q->opcode = RIVAL(inbuf,4);
|
||||
q->assoc_ctx = RIVAL(inbuf,8);
|
||||
q->mess_type = RIVAL(inbuf,12);
|
||||
if(!check_buffer(inbuf, 16))
|
||||
return;
|
||||
|
||||
q->data_size = RIVAL(inbuf->buffer, inbuf->offset+0);
|
||||
q->opcode = RIVAL(inbuf->buffer, inbuf->offset+4);
|
||||
q->assoc_ctx = RIVAL(inbuf->buffer, inbuf->offset+8);
|
||||
q->mess_type = RIVAL(inbuf->buffer, inbuf->offset+12);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
decode a start association request
|
||||
********************************************************************/
|
||||
static void decode_start_assoc_request(char *inbuf, START_ASSOC_REQUEST *q)
|
||||
static void decode_start_assoc_request(struct BUFFER *inbuf, START_ASSOC_REQUEST *q)
|
||||
{
|
||||
q->assoc_ctx = RIVAL(inbuf, 0);
|
||||
q->min_ver = RSVAL(inbuf, 4);
|
||||
q->maj_ver = RSVAL(inbuf, 6);
|
||||
if(!check_buffer(inbuf, 8))
|
||||
return;
|
||||
|
||||
q->assoc_ctx = RIVAL(inbuf->buffer, inbuf->offset+0);
|
||||
q->min_ver = RSVAL(inbuf->buffer, inbuf->offset+4);
|
||||
q->maj_ver = RSVAL(inbuf->buffer, inbuf->offset+6);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
decode a start association reply
|
||||
********************************************************************/
|
||||
static void decode_start_assoc_reply(char *inbuf, START_ASSOC_REPLY *r)
|
||||
static void decode_start_assoc_reply(struct BUFFER *inbuf, START_ASSOC_REPLY *r)
|
||||
{
|
||||
r->assoc_ctx=RIVAL(inbuf, 0);
|
||||
r->min_ver = RSVAL(inbuf, 4);
|
||||
r->maj_ver = RSVAL(inbuf, 6);
|
||||
if(!check_buffer(inbuf, 8))
|
||||
return;
|
||||
|
||||
r->assoc_ctx=RIVAL(inbuf->buffer, inbuf->offset+0);
|
||||
r->min_ver = RSVAL(inbuf->buffer, inbuf->offset+4);
|
||||
r->maj_ver = RSVAL(inbuf->buffer, inbuf->offset+6);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
decode a start association reply
|
||||
********************************************************************/
|
||||
static void decode_stop_assoc(char *inbuf, STOP_ASSOC *r)
|
||||
static void decode_stop_assoc(struct BUFFER *inbuf, STOP_ASSOC *r)
|
||||
{
|
||||
r->reason=RIVAL(inbuf, 0);
|
||||
if(!check_buffer(inbuf, 4))
|
||||
return;
|
||||
|
||||
r->reason=RIVAL(inbuf->buffer, inbuf->offset);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
decode a packet and fill a generic structure
|
||||
****************************************************************************/
|
||||
void decode_generic_packet(char *inbuf, GENERIC_PACKET *q)
|
||||
void decode_generic_packet(struct BUFFER *inbuf, GENERIC_PACKET *q)
|
||||
{
|
||||
read_generic_header(inbuf, &q->header);
|
||||
|
||||
inbuf->offset+=16;
|
||||
|
||||
switch (q->header.mess_type) {
|
||||
case 0:
|
||||
decode_start_assoc_request(inbuf+16, &q->sa_rq);
|
||||
decode_start_assoc_request(inbuf, &q->sa_rq);
|
||||
break;
|
||||
case 1:
|
||||
decode_start_assoc_reply(inbuf+16, &q->sa_rp);
|
||||
decode_start_assoc_reply(inbuf, &q->sa_rp);
|
||||
break;
|
||||
case 2:
|
||||
decode_stop_assoc(inbuf+16, &q->so);
|
||||
decode_stop_assoc(inbuf, &q->so);
|
||||
break;
|
||||
case 3:
|
||||
decode_replicate(inbuf+16, &q->rep);
|
||||
decode_replicate(inbuf, &q->rep);
|
||||
break;
|
||||
default:
|
||||
DEBUG(0,("decode_generic_packet: unknown message type:%d\n", q->header.mess_type));
|
||||
@ -296,6 +357,9 @@ void decode_generic_packet(char *inbuf, GENERIC_PACKET *q)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
encode a WINS_OWNER struct
|
||||
****************************************************************************/
|
||||
static void encode_wins_owner(struct BUFFER *outbuf, WINS_OWNER *wins_owner)
|
||||
{
|
||||
if (!grow_buffer(outbuf, 24))
|
||||
@ -316,6 +380,9 @@ static void encode_wins_owner(struct BUFFER *outbuf, WINS_OWNER *wins_owner)
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
encode a WINS_NAME struct
|
||||
****************************************************************************/
|
||||
static void encode_wins_name(struct BUFFER *outbuf, WINS_NAME *wins_name)
|
||||
{
|
||||
int i;
|
||||
@ -366,7 +433,7 @@ static void encode_wins_name(struct BUFFER *outbuf, WINS_NAME *wins_name)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
decode a update notification request
|
||||
encode a update notification request
|
||||
****************************************************************************/
|
||||
static void encode_update_notify_request(struct BUFFER *outbuf, UPDATE_NOTIFY_REQUEST *un_rq)
|
||||
{
|
||||
@ -464,7 +531,7 @@ static void encode_replicate(struct BUFFER *outbuf, REPLICATE *rep)
|
||||
encode_update_notify_request(outbuf, &rep->un_rq);
|
||||
break;
|
||||
default:
|
||||
DEBUG(0,("decode_replicate: unknown message type:%d\n", rep->msg_type));
|
||||
DEBUG(0,("encode_replicate: unknown message type:%d\n", rep->msg_type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,9 @@ verify if we know this partner
|
||||
BOOL check_partner(int assoc)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
DEBUG(0,("check_partner: total_current_partners: %d\n", total_current_partners));
|
||||
|
||||
for (i=0; i<total_current_partners; i++)
|
||||
if (current_partners[i].client_assoc==assoc)
|
||||
return True;
|
||||
@ -44,6 +46,8 @@ add a new entry to the list
|
||||
********************************************************************/
|
||||
BOOL add_partner(int client_assoc, int server_assoc, BOOL pull, BOOL push)
|
||||
{
|
||||
DEBUG(0,("add_partner: total_current_partners: %d\n", total_current_partners));
|
||||
|
||||
if (total_current_partners==64)
|
||||
return False;
|
||||
|
||||
@ -64,6 +68,8 @@ BOOL remove_partner(int client_assoc)
|
||||
{
|
||||
int i,j;
|
||||
|
||||
DEBUG(0,("remove_partner: total_current_partners: %d\n", total_current_partners));
|
||||
|
||||
for (i=0; current_partners[i].client_assoc!=client_assoc && i<total_current_partners; i++)
|
||||
;
|
||||
|
||||
@ -91,6 +97,8 @@ BOOL update_server_partner(int client_assoc, int server_assoc)
|
||||
{
|
||||
int i;
|
||||
|
||||
DEBUG(0,("update_server_partner: total_current_partners: %d\n", total_current_partners));
|
||||
|
||||
for (i=0; i<total_current_partners; i++)
|
||||
if (current_partners[i].client_assoc==client_assoc) {
|
||||
current_partners[i].server_assoc=server_assoc;
|
||||
@ -107,6 +115,8 @@ BOOL check_pull_partner(int assoc)
|
||||
{
|
||||
int i;
|
||||
|
||||
DEBUG(0,("check_pull_partner: total_current_partners: %d\n", total_current_partners));
|
||||
|
||||
for (i=0; i<total_current_partners; i++)
|
||||
if (current_partners[i].client_assoc==assoc &&
|
||||
current_partners[i].pull_partner==True)
|
||||
@ -122,6 +132,8 @@ BOOL check_push_partner(int assoc)
|
||||
{
|
||||
int i;
|
||||
|
||||
DEBUG(0,("check_push_partner: total_current_partners: %d\n", total_current_partners));
|
||||
|
||||
for (i=0; i<total_current_partners; i++)
|
||||
if (current_partners[i].client_assoc==assoc &&
|
||||
current_partners[i].push_partner==True)
|
||||
@ -137,6 +149,8 @@ int get_server_assoc(int assoc)
|
||||
{
|
||||
int i;
|
||||
|
||||
DEBUG(0,("get_server_assoc: total_current_partners: %d\n", total_current_partners));
|
||||
|
||||
for (i=0; i<total_current_partners; i++)
|
||||
if (current_partners[i].client_assoc==assoc)
|
||||
return current_partners[i].server_assoc;
|
||||
@ -152,6 +166,8 @@ BOOL write_server_assoc_table(int client_assoc, struct in_addr partner, struct i
|
||||
{
|
||||
int i;
|
||||
|
||||
DEBUG(0,("write_server_assoc_table: total_current_partners: %d\n", total_current_partners));
|
||||
|
||||
for (i=0; i<total_current_partners; i++)
|
||||
if (current_partners[i].client_assoc==client_assoc) {
|
||||
current_partners[i].partner_server=partner;
|
||||
@ -169,6 +185,8 @@ BOOL get_server_assoc_table(int client_assoc, struct in_addr *partner, struct in
|
||||
{
|
||||
int i;
|
||||
|
||||
DEBUG(0,("get_server_assoc_table: total_current_partners: %d\n", total_current_partners));
|
||||
|
||||
for (i=0; i<total_current_partners; i++)
|
||||
if (current_partners[i].client_assoc==client_assoc) {
|
||||
partner->s_addr=current_partners[i].partner_server.s_addr;
|
||||
|
@ -212,7 +212,7 @@ static void send_version_number_map_table(GENERIC_PACKET *q, GENERIC_PACKET *r)
|
||||
int s_ctx=get_server_assoc(q->header.assoc_ctx);
|
||||
|
||||
if (s_ctx==0) {
|
||||
DEBUG(0, ("send_entry_reply: request for a partner not in our table\n"));
|
||||
DEBUG(0, ("send_version_number_map_table: request for a partner not in our table\n"));
|
||||
stop_packet(q, r, STOP_REASON_USER_REASON);
|
||||
return;
|
||||
}
|
||||
@ -382,7 +382,7 @@ static void receive_version_number_map_table(GENERIC_PACKET *q, GENERIC_PACKET *
|
||||
* if this server have newer records than what we have
|
||||
* for several wins servers, we need to ask it.
|
||||
* Alas a send entry request is only on one server.
|
||||
* So in the send entry reply, we'll ask for the next server is required.
|
||||
* So in the send entry reply, we'll ask for the next server if required.
|
||||
*/
|
||||
|
||||
if (check_partners_and_send_entries(q, r, i))
|
||||
@ -586,7 +586,7 @@ static void update_notify_request(GENERIC_PACKET *q, GENERIC_PACKET *r)
|
||||
int s_ctx=get_server_assoc(q->header.assoc_ctx);
|
||||
|
||||
if (s_ctx==0) {
|
||||
DEBUG(0, ("send_entry_reply: request for a partner not in our table\n"));
|
||||
DEBUG(0, ("update_notify_request: request for a partner not in our table\n"));
|
||||
stop_packet(q, r, STOP_REASON_USER_REASON);
|
||||
return;
|
||||
}
|
||||
@ -799,11 +799,6 @@ static BOOL switch_message(GENERIC_PACKET *q, GENERIC_PACKET *r)
|
||||
break;
|
||||
case 2:
|
||||
/* stop association message */
|
||||
/*
|
||||
* remove the partner from the list and
|
||||
* reply false to NOT send a packet
|
||||
*/
|
||||
remove_partner(q->header.assoc_ctx);
|
||||
return False;
|
||||
break;
|
||||
case 3:
|
||||
@ -868,8 +863,10 @@ void construct_reply(struct wins_packet_struct *p)
|
||||
|
||||
/* if we got a stop assoc or if we send a stop assoc, close the fd after */
|
||||
if (p->packet->header.mess_type==MESSAGE_TYPE_STOP_ASSOC ||
|
||||
r.header.mess_type==MESSAGE_TYPE_STOP_ASSOC)
|
||||
r.header.mess_type==MESSAGE_TYPE_STOP_ASSOC) {
|
||||
remove_partner(p->packet->header.assoc_ctx);
|
||||
p->stop_packet=True;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -929,6 +926,48 @@ void run_pull_replication(time_t t)
|
||||
void run_push_replication(time_t t)
|
||||
{
|
||||
/* we push every 30 minutes or 25 new entries */
|
||||
int i, s;
|
||||
struct BUFFER buffer;
|
||||
GENERIC_PACKET p;
|
||||
|
||||
buffer.buffer=NULL;
|
||||
buffer.offset=0;
|
||||
buffer.length=0;
|
||||
|
||||
for (i=1; i<partner_count; i++) {
|
||||
if (global_wins_table[0][i].last_pull < t) {
|
||||
global_wins_table[0][i].last_pull=t+30*60; /* next in 30 minutes */
|
||||
|
||||
/* contact the wins server */
|
||||
p.header.mess_type=MESSAGE_TYPE_START_ASSOC_REQUEST;
|
||||
p.header.opcode=OPCODE_NON_NBT;
|
||||
p.header.assoc_ctx=0;
|
||||
p.sa_rq.assoc_ctx=(int)t;
|
||||
p.sa_rq.min_ver=1;
|
||||
p.sa_rq.maj_ver=1;
|
||||
|
||||
DEBUG(3,("run_push_replication: contacting wins server %s.\n", inet_ntoa(global_wins_table[0][i].address)));
|
||||
encode_generic_packet(&buffer, &p);
|
||||
dump_generic_packet(&p);
|
||||
|
||||
/* send the packet to the server and add the descriptor to receive answers */
|
||||
s=open_socket_out(SOCK_STREAM, &global_wins_table[0][i].address, 42, LONG_CONNECT_TIMEOUT);
|
||||
if (s==-1) {
|
||||
DEBUG(0,("run_push_replication: can't contact wins server %s.\n", inet_ntoa(global_wins_table[0][i].address)));
|
||||
return;
|
||||
}
|
||||
|
||||
if(buffer.offset > 0) {
|
||||
if (!send_smb(s, buffer.buffer))
|
||||
exit_server("run_push_replication: send_smb failed.");
|
||||
}
|
||||
|
||||
add_fd_to_sock_array(s);
|
||||
FD_SET(s, listen_set);
|
||||
|
||||
/* add ourself as a client */
|
||||
add_partner((int)t, 0, False, True);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,17 +304,49 @@ static struct wins_packet_struct *read_wins_packet(int fd, int timeout)
|
||||
{
|
||||
struct wins_packet_struct *p;
|
||||
GENERIC_PACKET *q;
|
||||
char buf[4096];
|
||||
struct BUFFER inbuf;
|
||||
ssize_t len=0;
|
||||
size_t total=0;
|
||||
ssize_t ret;
|
||||
BOOL ok = False;
|
||||
|
||||
if (!receive_smb(fd, buf, timeout))
|
||||
inbuf.buffer=NULL;
|
||||
inbuf.length=0;
|
||||
inbuf.offset=0;
|
||||
|
||||
if(!grow_buffer(&inbuf, 4))
|
||||
return NULL;
|
||||
|
||||
ok = (read(fd, inbuf.buffer,4) == 4);
|
||||
if (!ok)
|
||||
return NULL;
|
||||
len = smb_len(inbuf.buffer);
|
||||
|
||||
if (len<=0)
|
||||
return NULL;
|
||||
|
||||
if(!grow_buffer(&inbuf, len))
|
||||
return NULL;
|
||||
|
||||
while (total < len) {
|
||||
ret = read(fd, inbuf.buffer + total + 4, len - total);
|
||||
if (ret == 0) {
|
||||
DEBUG(10,("read_socket_data: recv of %d returned 0. Error = %s\n", (int)(len - total), strerror(errno) ));
|
||||
return NULL;
|
||||
}
|
||||
if (ret == -1) {
|
||||
DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(len - total), strerror(errno) ));
|
||||
return NULL;
|
||||
}
|
||||
total += ret;
|
||||
}
|
||||
|
||||
q = (GENERIC_PACKET *)talloc(mem_ctx, sizeof(GENERIC_PACKET));
|
||||
p = (struct wins_packet_struct *)talloc(mem_ctx, sizeof(*p));
|
||||
if (q==NULL || p==NULL)
|
||||
return NULL;
|
||||
|
||||
decode_generic_packet(buf, q);
|
||||
decode_generic_packet(&inbuf, q);
|
||||
|
||||
q->fd=fd;
|
||||
|
||||
@ -403,7 +435,10 @@ static BOOL listen_for_wins_packets(void)
|
||||
|
||||
/* accept and add the new socket to the listen set */
|
||||
new_s=accept(s, &addr, &in_addrlen);
|
||||
|
||||
|
||||
if (new_s < 0)
|
||||
continue;
|
||||
|
||||
DEBUG(5,("listen_for_wins_packets: new connection, old: %d, new : %d\n", s, new_s));
|
||||
|
||||
set_socket_options(new_s, "SO_KEEPALIVE");
|
||||
|
Loading…
Reference in New Issue
Block a user