received properly when a UDP "retry" occurs. it's because reads and
writes must be interleaved / matched.
scenario:
nmblookup connects to agent, sends request.
agent receives request, broadcasts it on 137.
agent RECEIVES 137 broadcast, sends it to nmblookup
agent receives RESPONSE to 137 broadcast, sends it to nmblookup.
if reads are not equally interspersed with writes, then second send
will fail.
if you think this is odd behaviour and that the agent should be filtering
its own UDP traffic, think again.
agent will be, potentially, redirecting nmbd traffic (including WINS
server) not just client programs.
(This used to be commit
43e158c4261e51678d6e7f77ceb4a1c7281a2525)
struct packet_struct *p2;
struct nmb_packet *nmb = &p.packet.nmb;
int packet_type = NMB_PACKET;
+ BOOL first_time = True;
if (fd == -1)
{
GetTimeOfDay(&tval);
- if (!send_packet(&p))
- {
- if (packet_type == NMB_SOCK_PACKET) close(fd);
- return(False);
- }
-
- retries--;
-
while (1)
{
struct timeval tval2;
GetTimeOfDay(&tval2);
- if (TvalDiff(&tval,&tval2) > retry_time) {
- if (!retries) break;
+ if (first_time || TvalDiff(&tval,&tval2) > retry_time)
+ {
+ first_time = False;
if (!found && !send_packet(&p))
{
if (packet_type == NMB_SOCK_PACKET) close(fd);
return False;
}
GetTimeOfDay(&tval);
- retries--;
}
if ((p2=receive_packet(fd,packet_type,90)))
continue;
}
+ retries--;
+
_interpret_node_status(&nmb2->answers->rdata[0], master,rname);
free_packet(p2);
if (packet_type == NMB_SOCK_PACKET) close(fd);
{
BOOL found=False;
int i, retries = 3;
- int retry_time = bcast?250:2000;
+ int retry_time = bcast?2000:2000;
struct timeval tval;
struct packet_struct p;
struct packet_struct *p2;
struct nmb_packet *nmb = &p.packet.nmb;
struct in_addr *ip_list = NULL;
BOOL packet_type = NMB_PACKET;
+ BOOL first_send = True;
if (fd == -1)
{
- retries = 0;
+ retries = 1;
packet_type = NMB_SOCK_PACKET;
fd = get_nmb_sock();
p.timestamp = time(NULL);
p.packet_type = packet_type;
- ZERO_STRUCT(tval);
+ GetTimeOfDay(&tval);
while (retries >= 0)
{
struct timeval tval2;
GetTimeOfDay(&tval2);
- if (TvalDiff(&tval,&tval2) > retry_time)
+ if (first_send ) /* || TvalDiff(&tval,&tval2) > retry_time) */
{
+ first_send = False;
if (!found && !send_packet(&p))
{
if (packet_type == NMB_SOCK_PACKET) close(fd);
fn(p2);
else
free_packet(p2);
+
continue;
}
}
length = read_udp_socket(fd,buf,sizeof(buf));
-
+
dump_data(100, buf, length);
+ if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
+ {
+ uint16 trn_id = 0;
+ if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
+ {
+ return False;
+ }
+ }
+
if (length < MIN_DGRAM_SIZE) return(NULL);
if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
char buf[1024];
int len=0;
+ DEBUG(100,("send_packet: %d %d\n", p->fd, p->packet_type));
+
bzero(buf,sizeof(buf));
switch (p->packet_type)
if (write(p->fd,qbuf,qlen) != qlen)
{
+ DEBUG(0,("send_packet: write hdr failed\n"));
return False;
}
- qlen = read(p->fd, &trn_id, sizeof(trn_id));
-
- if (qlen != sizeof(trn_id))
+ if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
+ {
+ DEBUG(0,("send_packet: 1st ack failed\n"));
+ return False;
+ }
+ if (write(p->fd,buf,len) != len)
+ {
+ DEBUG(0,("send_packet: write packet failed\n"));
+ return False;
+ }
+ if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
{
+ DEBUG(0,("send_packet: 2nd ack failed\n"));
return False;
}
- return write(p->fd,buf,len) == len;
+ return True;
}
}
timeout.tv_sec = t/1000;
timeout.tv_usec = 1000*(t%1000);
+ DEBUG(100,("receive_packet: %d %d\n", fd, type));
sys_select(fd+1,&fds,NULL, &timeout);
if (FD_ISSET(fd,&fds))
nmb = (struct nmb_state*)malloc(sizeof(struct nmb_state));
if (nmb == NULL)
{
- free(p);
+ free_packet(p);
return False;
}
if (!send_packet(p))
{
DEBUG(0,("server is dead\n"));
- free(p);
+ free_packet(p);
return False;
}
- free(p);
+ free_packet(p);
return True;
}
p = receive_packet(fd, NMB_PACKET, 0);
if (p == NULL)
{
- return False;
+ return True;
}
+#if 0
if (!p->packet.nmb.header.response)
{
- free(p);
+ DEBUG(10,("skipping response packet\n"));
+ free_packet(p);
return True;
}
+#endif
nmb_id = p->packet.nmb.header.name_trn_id;
DEBUG(10,("process_srv_sock:\tnmb_id:\t%d\n", nmb_id));
}
return True;
}
- return False;
+ return True;
}
static int get_agent_sock(void*id)
return -1;
}
- chmod(path, 0666);
+ chmod(path, 0777);
if (listen(s, 5) == -1)
{