00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023
00024 static TDB_CONTEXT *tdbd = NULL;
00025
00026
00027 struct unexpected_key {
00028 enum packet_type packet_type;
00029 time_t timestamp;
00030 int count;
00031 };
00032
00033
00034
00035
00036
00037
00038
00039
00040 void unexpected_packet(struct packet_struct *p)
00041 {
00042 static int count;
00043 TDB_DATA kbuf, dbuf;
00044 struct unexpected_key key;
00045 char buf[1024];
00046 int len=0;
00047
00048 if (!tdbd) {
00049 tdbd = tdb_open_log(lock_path("unexpected.tdb"), 0,
00050 TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
00051 O_RDWR | O_CREAT, 0644);
00052 if (!tdbd) {
00053 DEBUG(0,("Failed to open unexpected.tdb\n"));
00054 return;
00055 }
00056 }
00057
00058 memset(buf,'\0',sizeof(buf));
00059
00060 len = build_packet(buf, p);
00061
00062 ZERO_STRUCT(key);
00063
00064 key.packet_type = p->packet_type;
00065 key.timestamp = p->timestamp;
00066 key.count = count++;
00067
00068 kbuf.dptr = (char *)&key;
00069 kbuf.dsize = sizeof(key);
00070 dbuf.dptr = buf;
00071 dbuf.dsize = len;
00072
00073 tdb_store(tdbd, kbuf, dbuf, TDB_REPLACE);
00074 }
00075
00076
00077 static time_t lastt;
00078
00079
00080
00081
00082 static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
00083 {
00084 struct unexpected_key key;
00085
00086 if (kbuf.dsize != sizeof(key)) {
00087 tdb_delete(ttdb, kbuf);
00088 }
00089
00090 memcpy(&key, kbuf.dptr, sizeof(key));
00091
00092 if (lastt - key.timestamp > NMBD_UNEXPECTED_TIMEOUT) {
00093 tdb_delete(ttdb, kbuf);
00094 }
00095
00096 return 0;
00097 }
00098
00099
00100
00101
00102
00103 void clear_unexpected(time_t t)
00104 {
00105 if (!tdbd) return;
00106
00107 if ((lastt != 0) && (t < lastt + NMBD_UNEXPECTED_TIMEOUT))
00108 return;
00109
00110 lastt = t;
00111
00112 tdb_traverse(tdbd, traverse_fn, NULL);
00113 }
00114
00115
00116 static struct packet_struct *matched_packet;
00117 static int match_id;
00118 static enum packet_type match_type;
00119 static const char *match_name;
00120
00121
00122
00123
00124 static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
00125 {
00126 struct unexpected_key key;
00127 struct packet_struct *p;
00128
00129 if (kbuf.dsize != sizeof(key)) {
00130 return 0;
00131 }
00132
00133 memcpy(&key, kbuf.dptr, sizeof(key));
00134
00135 if (key.packet_type != match_type) return 0;
00136
00137 p = parse_packet(dbuf.dptr, dbuf.dsize, match_type);
00138
00139 if ((match_type == NMB_PACKET &&
00140 p->packet.nmb.header.name_trn_id == match_id) ||
00141 (match_type == DGRAM_PACKET &&
00142 match_mailslot_name(p, match_name))) {
00143 matched_packet = p;
00144 return -1;
00145 }
00146
00147 free_packet(p);
00148
00149 return 0;
00150 }
00151
00152
00153
00154
00155
00156 struct packet_struct *receive_unexpected(enum packet_type packet_type, int id,
00157 const char *mailslot_name)
00158 {
00159 TDB_CONTEXT *tdb2;
00160
00161 tdb2 = tdb_open_log(lock_path("unexpected.tdb"), 0, 0, O_RDONLY, 0);
00162 if (!tdb2) return NULL;
00163
00164 matched_packet = NULL;
00165 match_id = id;
00166 match_type = packet_type;
00167 match_name = mailslot_name;
00168
00169 tdb_traverse(tdb2, traverse_match, NULL);
00170
00171 tdb_close(tdb2);
00172
00173 return matched_packet;
00174 }