1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

- added predict.c, moving the routines from util.c

- added iface_count() and iface_n_ip() routines so its easy to loop
over the local interface list

- made readsize a normal loadparm global

- check for null w in add_domain_entry()

- set the deathtime to time()-1 for doamin entries with servertype==0
This allows servers that are shutting down to be removed

- add the 0x1c name at startup if we are a WINS server. Previously we
added it only if we were a master

- loop over interfaces in add_my_domains(), so people don't have to
have a lmhosts file to get lp_workgroup() on all interfaces

- set add to True for find_workgroupstruct() in nmbsync, and check for
null return

- remove some ugly "errno = EBADF" bits. they just confused things.
This commit is contained in:
Andrew Tridgell 0001-01-01 00:00:00 +00:00
parent 5a0d016b24
commit 88b191b488
12 changed files with 220 additions and 155 deletions

View File

@ -67,6 +67,8 @@ void load_interfaces(void);
void iface_set_default(char *ip,char *bcast,char *nmask);
BOOL ismyip(struct in_addr ip);
BOOL ismybcast(struct in_addr bcast);
int iface_count(void);
struct in_addr *iface_n_ip(int n);
struct in_addr *iface_bcast(struct in_addr ip);
struct in_addr *iface_nmask(struct in_addr ip);
struct in_addr *iface_ip(struct in_addr ip);
@ -197,7 +199,7 @@ void sync_server(enum cmd_type cmd, char *serv_name, char *work_name,
int name_type,
struct in_addr ip);
void update_from_reg(char *name, int type, struct in_addr ip);
void add_my_domains(void);
void add_my_domains(char *group);
BOOL same_context(struct dgram_packet *dgram);
BOOL listening_name(struct work_record *work, struct nmb_name *n);
void process_logon_packet(struct packet_struct *p,char *buf,int len);
@ -239,6 +241,9 @@ BOOL server_cryptkey(char *buf);
BOOL server_validate(char *buf);
BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname);
void pcap_printer_fn(void (*fn)());
int read_predict(int fd,int offset,char *buf,char **ptr,int num);
void do_read_prediction();
void invalidate_read_prediction(int fd);
void lpq_reset(int snum);
void print_file(int fnum);
int get_printqueue(int snum,int cnum,print_queue_struct **queue,
@ -457,9 +462,6 @@ int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew);
BOOL send_keepalive(int client);
int read_data(int fd,char *buffer,int N);
int write_data(int fd,char *buffer,int N);
int read_predict(int fd,int offset,char *buf,char **ptr,int num);
void do_read_prediction();
void invalidate_read_prediction(int fd);
int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align);
int read_smb_length(int fd,char *inbuf,int timeout);
BOOL receive_smb(int fd,char *buffer,int timeout);

View File

@ -388,6 +388,33 @@ BOOL ismybcast(struct in_addr bcast)
return False;
}
/****************************************************************************
how many interfaces do we have
**************************************************************************/
int iface_count(void)
{
int ret = 0;
struct interface *i;
for (i=interfaces;i;i=i->next)
ret++;
return ret;
}
/****************************************************************************
return IP of the Nth interface
**************************************************************************/
struct in_addr *iface_n_ip(int n)
{
struct interface *i;
for (i=interfaces;i && n;i=i->next)
n--;
if (i) return &i->ip;
return NULL;
}
static struct interface *iface_find(struct in_addr ip)
{
struct interface *i;

View File

@ -56,10 +56,6 @@ int trans_num = 0;
*/
int case_default = CASE_LOWER;
/* size of reads during a direct file to file transfer */
int ReadSize = 16*1024;
pstring debugf = "/tmp/log.samba";
int syslog_level;
@ -1951,7 +1947,6 @@ int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out,BOOL
/* Check if error */
if(selrtn == -1) {
errno = EBADF;
return -1;
}
@ -1974,7 +1969,6 @@ int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out,BOOL
/* force a particular error number for
portability */
DEBUG(5,("read gave error %s\n",strerror(errno)));
errno = EBADF;
return -1;
}
@ -2068,10 +2062,6 @@ int read_data(int fd,char *buffer,int N)
{
ret = read(fd,buffer + total,N - total);
/* this is for portability */
if (ret < 0)
errno = EBADF;
if (ret <= 0)
return total;
total += ret;
@ -2101,142 +2091,28 @@ int write_data(int fd,char *buffer,int N)
}
/* variables used by the read prediction module */
int rp_fd = -1;
int rp_offset = 0;
int rp_length = 0;
int rp_alloced = 0;
int rp_predict_fd = -1;
int rp_predict_offset = 0;
int rp_predict_length = 0;
int rp_timeout = 5;
time_t rp_time = 0;
char *rp_buffer = NULL;
BOOL predict_skip=False;
time_t smb_last_time=(time_t)0;
/****************************************************************************
handle read prediction on a file
****************************************************************************/
int read_predict(int fd,int offset,char *buf,char **ptr,int num)
{
int ret = 0;
int possible = rp_length - (offset - rp_offset);
possible = MIN(possible,num);
/* give data if possible */
if (fd == rp_fd &&
offset >= rp_offset &&
possible>0 &&
smb_last_time-rp_time < rp_timeout)
{
ret = possible;
if (buf)
memcpy(buf,rp_buffer + (offset-rp_offset),possible);
else
*ptr = rp_buffer + (offset-rp_offset);
DEBUG(5,("read-prediction gave %d bytes of %d\n",ret,num));
}
if (ret == num) {
predict_skip = True;
} else {
predict_skip = False;
/* prepare the next prediction */
rp_predict_fd = fd;
rp_predict_offset = offset + num;
rp_predict_length = num;
}
if (ret < 0) ret = 0;
return(ret);
}
/****************************************************************************
pre-read some data
****************************************************************************/
void do_read_prediction()
{
if (predict_skip) return;
if (rp_predict_fd == -1)
return;
rp_fd = rp_predict_fd;
rp_offset = rp_predict_offset;
rp_length = 0;
rp_predict_fd = -1;
rp_predict_length = MIN(rp_predict_length,2*ReadSize);
rp_predict_length = MAX(rp_predict_length,1024);
rp_offset = (rp_offset/1024)*1024;
rp_predict_length = (rp_predict_length/1024)*1024;
if (rp_predict_length > rp_alloced)
{
rp_buffer = Realloc(rp_buffer,rp_predict_length);
rp_alloced = rp_predict_length;
if (!rp_buffer)
{
DEBUG(0,("can't allocate read-prediction buffer\n"));
rp_predict_fd = -1;
rp_fd = -1;
rp_alloced = 0;
return;
}
}
if (lseek(rp_fd,rp_offset,SEEK_SET) != rp_offset) {
rp_fd = -1;
rp_predict_fd = -1;
return;
}
rp_length = read(rp_fd,rp_buffer,rp_predict_length);
rp_time = time(NULL);
if (rp_length < 0)
rp_length = 0;
}
/****************************************************************************
invalidate read-prediction on a fd
****************************************************************************/
void invalidate_read_prediction(int fd)
{
if (rp_fd == fd)
rp_fd = -1;
if (rp_predict_fd == fd)
rp_predict_fd = -1;
}
/****************************************************************************
transfer some data between two fd's
****************************************************************************/
int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
{
static char *buf=NULL;
static int size=0;
char *buf1,*abuf;
static int size = 0;
int total = 0;
DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
if ((size < ReadSize) && buf) {
free(buf);
buf = NULL;
if (size == 0) {
size = lp_readsize();
size = MAX(size,1024);
}
size = MAX(ReadSize,1024);
while (!buf && size>0) {
buf = (char *)Realloc(buf,size+8);
if (!buf) size /= 2;
}
if (!buf) {
DEBUG(0,("Can't allocate transfer buffer!\n"));
exit(1);

View File

@ -93,6 +93,7 @@ extern int lp_maxdisksize(void);
extern int lp_lpqcachetime(void);
extern int lp_syslog(void);
extern int lp_deadtime(void);
extern int lp_readsize(void);
extern int lp_debuglevel(void);
extern int lp_maxprotocol(void);
extern int lp_maxpacket(void);

View File

@ -460,6 +460,8 @@ struct domain_record *add_domain_entry(struct in_addr source_ip,
{
struct work_record *w = find_workgroupstruct(d, name, add);
if (!w) return NULL;
/* add WORKGROUP(1e) and WORKGROUP(00) entries into name database
or register with WINS server, if it's our workgroup */
if (strequal(lp_workgroup(), name))
@ -586,7 +588,8 @@ struct server_record *add_server_entry(struct domain_record *d,
if (ismybcast(d->bcast_ip) &&
strequal(lp_workgroup(),work->work_group))
{
servertype |= SV_TYPE_LOCAL_LIST_ONLY;
if (servertype)
servertype |= SV_TYPE_LOCAL_LIST_ONLY;
}
else
{
@ -599,6 +602,9 @@ struct server_record *add_server_entry(struct domain_record *d,
strupper(s->serv.name);
s->serv.type = servertype;
s->death_time = ttl?time(NULL)+ttl*3:0;
if (servertype == 0)
s->death_time = time(NULL)-1;
/* for a domain entry, the comment field refers to the server name */

View File

@ -178,8 +178,6 @@ static void become_master(struct domain_record *d, struct work_record *work)
/* add domain master and domain member names or register with WINS */
add_name_entry(work->work_group,0x1b,NB_ACTIVE );
add_name_entry(work->work_group,0x1c,NB_ACTIVE|NB_GROUP);
work->ServerType |= SV_TYPE_DOMAIN_MASTER;
if (lp_domain_logons())
@ -215,7 +213,6 @@ void become_nonmaster(struct domain_record *d, struct work_record *work)
work->ElectionCriterion &= ~0x4;
remove_name_entry(work->work_group,0x1b);
remove_name_entry(work->work_group,0x1c);
remove_name_entry(work->work_group,0x1d);
remove_name_entry(MSBROWSE ,0x01);
}

View File

@ -267,6 +267,11 @@ void add_my_names(void)
add_netbios_entry("*",0x0,NB_ACTIVE,0,SELF,ip,False);
add_netbios_entry("__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip,False);
add_netbios_entry("__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip,False);
if (lp_wins_support()) {
/* the 0x1c name gets added by any WINS server it seems */
add_name_entry(my_workgroup(),0x1c,NB_ACTIVE|NB_GROUP);
}
}
/*******************************************************************

View File

@ -270,16 +270,19 @@ void update_from_reg(char *name, int type, struct in_addr ip)
/****************************************************************************
add the default workgroup into my domain
**************************************************************************/
void add_my_domains(void)
void add_my_domains(char *group)
{
/* add or find domain on our local subnet, in the default workgroup */
if (*lp_workgroup() != '*')
{
add_domain_entry(*iface_bcast(ipzero),
*iface_nmask(ipzero),
lp_workgroup(), True);
}
int n,i;
struct in_addr *ip;
if (*group == '*') return;
n = iface_count();
for (i=0;i<n;i++) {
ip = iface_n_ip(i);
if (!ip) return;
add_domain_entry(*iface_bcast(*ip),*iface_nmask(*ip),lp_workgroup(),True);
}
}
@ -728,7 +731,7 @@ static void process_reset_browser(struct packet_struct *p,char *buf)
struct work_record *work;
for (work=d->workgrouplist;work;work=remove_workgroup(d,work));
}
add_my_domains();
add_my_domains(lp_workgroup());
}
/* stop browsing altogether. i don't think this is a good idea! */

View File

@ -492,7 +492,7 @@ static void usage(char *pname)
return(-1);
if (*group)
add_domain_entry(*iface_bcast(ipzero),*iface_nmask(ipzero),group, True);
add_my_domains(group);
if (!is_daemon && !is_a_socket(0)) {
DEBUG(0,("standard input is not a socket, assuming -D option\n"));
@ -519,7 +519,7 @@ static void usage(char *pname)
string_sub(ServerComment,"%h",myhostname);
add_my_names();
add_my_domains();
add_my_domains(lp_workgroup());
DEBUG(3,("Checked names\n"));

View File

@ -103,7 +103,6 @@ static BOOL add_info(struct domain_record *d, struct work_record *work, int serv
uint32 stype = IVAL(p,18);
int comment_offset = IVAL(p,22) & 0xFFFF;
char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
struct work_record *w = work;
DEBUG(4, ("\t%-16.16s %08x %s\n", sname, stype, cmnt));
@ -111,16 +110,17 @@ static BOOL add_info(struct domain_record *d, struct work_record *work, int serv
if (stype & SV_TYPE_DOMAIN_ENUM)
{
/* creates workgroup on remote subnet */
if ((w = find_workgroupstruct(d,sname, False)))
if ((w = find_workgroupstruct(d,sname, True)))
{
if (ismybcast(d->bcast_ip))
{
announce_request(w, d->bcast_ip);
}
}
}
}
add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False);
if (w)
add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False);
}
}
}

View File

@ -56,7 +56,6 @@
BOOL bLoaded = False;
extern int DEBUGLEVEL;
extern int ReadSize;
extern pstring user_socket_options;
#ifndef GLOBAL_NAME
@ -149,6 +148,7 @@ typedef struct
int syslog;
int os_level;
int max_ttl;
int ReadSize;
BOOL bWINSsupport;
BOOL bWINSproxy;
BOOL bPreferredMaster;
@ -409,7 +409,7 @@ struct parm_struct
{"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL},
{"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL},
{"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL},
{"read size", P_INTEGER, P_GLOBAL, &ReadSize, NULL},
{"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL},
#ifdef KANJI
{"coding system", P_INTEGER, P_GLOBAL, &coding_system, handle_coding_system},
#endif /* KANJI */
@ -582,6 +582,7 @@ static void init_globals(void)
Globals.bBrowseList = True;
Globals.bWINSsupport = True;
Globals.bWINSproxy = False;
Globals.ReadSize = 16*1024;
#ifdef KANJI
coding_system = interpret_coding_system (KANJI, SJIS_CODE);
@ -735,6 +736,7 @@ FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
FN_GLOBAL_INTEGER(lp_security,&Globals.security)

146
source/smbd/predict.c Normal file
View File

@ -0,0 +1,146 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
file read prediction routines
Copyright (C) Andrew Tridgell 1992-1995
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 "includes.h"
#include "loadparm.h"
extern int DEBUGLEVEL;
/* variables used by the read prediction module */
static int rp_fd = -1;
static int rp_offset = 0;
static int rp_length = 0;
static int rp_alloced = 0;
static int rp_predict_fd = -1;
static int rp_predict_offset = 0;
static int rp_predict_length = 0;
static int rp_timeout = 5;
static time_t rp_time = 0;
static char *rp_buffer = NULL;
static BOOL predict_skip=False;
time_t smb_last_time=(time_t)0;
/****************************************************************************
handle read prediction on a file
****************************************************************************/
int read_predict(int fd,int offset,char *buf,char **ptr,int num)
{
int ret = 0;
int possible = rp_length - (offset - rp_offset);
possible = MIN(possible,num);
/* give data if possible */
if (fd == rp_fd &&
offset >= rp_offset &&
possible>0 &&
smb_last_time-rp_time < rp_timeout)
{
ret = possible;
if (buf)
memcpy(buf,rp_buffer + (offset-rp_offset),possible);
else
*ptr = rp_buffer + (offset-rp_offset);
DEBUG(5,("read-prediction gave %d bytes of %d\n",ret,num));
}
if (ret == num) {
predict_skip = True;
} else {
predict_skip = False;
/* prepare the next prediction */
rp_predict_fd = fd;
rp_predict_offset = offset + num;
rp_predict_length = num;
}
if (ret < 0) ret = 0;
return(ret);
}
/****************************************************************************
pre-read some data
****************************************************************************/
void do_read_prediction()
{
static int readsize = 0;
if (predict_skip) return;
if (rp_predict_fd == -1)
return;
rp_fd = rp_predict_fd;
rp_offset = rp_predict_offset;
rp_length = 0;
rp_predict_fd = -1;
if (readsize == 0) {
readsize = lp_readsize();
readsize = MAX(readsize,1024);
}
rp_predict_length = MIN(rp_predict_length,2*readsize);
rp_predict_length = MAX(rp_predict_length,1024);
rp_offset = (rp_offset/1024)*1024;
rp_predict_length = (rp_predict_length/1024)*1024;
if (rp_predict_length > rp_alloced)
{
rp_buffer = Realloc(rp_buffer,rp_predict_length);
rp_alloced = rp_predict_length;
if (!rp_buffer)
{
DEBUG(0,("can't allocate read-prediction buffer\n"));
rp_predict_fd = -1;
rp_fd = -1;
rp_alloced = 0;
return;
}
}
if (lseek(rp_fd,rp_offset,SEEK_SET) != rp_offset) {
rp_fd = -1;
rp_predict_fd = -1;
return;
}
rp_length = read(rp_fd,rp_buffer,rp_predict_length);
rp_time = time(NULL);
if (rp_length < 0)
rp_length = 0;
}
/****************************************************************************
invalidate read-prediction on a fd
****************************************************************************/
void invalidate_read_prediction(int fd)
{
if (rp_fd == fd)
rp_fd = -1;
if (rp_predict_fd == fd)
rp_predict_fd = -1;
}