00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "includes.h"
00025
00026 int num_response_packets = 0;
00027
00028
00029
00030
00031
00032 static void add_response_record(struct subnet_record *subrec,
00033 struct response_record *rrec)
00034 {
00035 num_response_packets++;
00036
00037 DEBUG(4,("add_response_record: adding response record id:%hu to subnet %s. num_records:%d\n",
00038 rrec->response_id, subrec->subnet_name, num_response_packets));
00039
00040 DLIST_ADD_END(subrec->responselist, rrec, struct response_record *);
00041 }
00042
00043
00044
00045
00046
00047 void remove_response_record(struct subnet_record *subrec,
00048 struct response_record *rrec)
00049 {
00050
00051
00052
00053
00054
00055 struct response_record *p = NULL;
00056
00057 for (p = subrec->responselist; p; p = p->next) {
00058 if (p == rrec) {
00059 break;
00060 }
00061 }
00062
00063 if (p == NULL) {
00064
00065 return;
00066 }
00067
00068 DLIST_REMOVE(subrec->responselist, rrec);
00069
00070 if(rrec->userdata) {
00071 if(rrec->userdata->free_fn) {
00072 (*rrec->userdata->free_fn)(rrec->userdata);
00073 } else {
00074 ZERO_STRUCTP(rrec->userdata);
00075 SAFE_FREE(rrec->userdata);
00076 }
00077 }
00078
00079
00080 rrec->packet->locked = False;
00081 free_packet(rrec->packet);
00082
00083 ZERO_STRUCTP(rrec);
00084 SAFE_FREE(rrec);
00085
00086 num_response_packets--;
00087 }
00088
00089
00090
00091
00092
00093 struct response_record *make_response_record( struct subnet_record *subrec,
00094 struct packet_struct *p,
00095 response_function resp_fn,
00096 timeout_response_function timeout_fn,
00097 success_function success_fn,
00098 fail_function fail_fn,
00099 struct userdata_struct *userdata)
00100 {
00101 struct response_record *rrec;
00102 struct nmb_packet *nmb = &p->packet.nmb;
00103
00104 if (!(rrec = SMB_MALLOC_P(struct response_record))) {
00105 DEBUG(0,("make_response_queue_record: malloc fail for response_record.\n"));
00106 return NULL;
00107 }
00108
00109 memset((char *)rrec, '\0', sizeof(*rrec));
00110
00111 rrec->response_id = nmb->header.name_trn_id;
00112
00113 rrec->resp_fn = resp_fn;
00114 rrec->timeout_fn = timeout_fn;
00115 rrec->success_fn = success_fn;
00116 rrec->fail_fn = fail_fn;
00117
00118 rrec->packet = p;
00119
00120 if(userdata) {
00121
00122 if(userdata->copy_fn) {
00123 if((rrec->userdata = (*userdata->copy_fn)(userdata)) == NULL) {
00124 DEBUG(0,("make_response_queue_record: copy fail for userdata.\n"));
00125 ZERO_STRUCTP(rrec);
00126 SAFE_FREE(rrec);
00127 return NULL;
00128 }
00129 } else {
00130
00131 if((rrec->userdata = (struct userdata_struct *)
00132 SMB_MALLOC(sizeof(struct userdata_struct)+userdata->userdata_len)) == NULL) {
00133 DEBUG(0,("make_response_queue_record: malloc fail for userdata.\n"));
00134 ZERO_STRUCTP(rrec);
00135 SAFE_FREE(rrec);
00136 return NULL;
00137 }
00138 rrec->userdata->copy_fn = userdata->copy_fn;
00139 rrec->userdata->free_fn = userdata->free_fn;
00140 rrec->userdata->userdata_len = userdata->userdata_len;
00141 memcpy(rrec->userdata->data, userdata->data, userdata->userdata_len);
00142 }
00143 } else {
00144 rrec->userdata = NULL;
00145 }
00146
00147 rrec->num_msgs = 0;
00148
00149 if(!nmb->header.nm_flags.bcast)
00150 rrec->repeat_interval = 5;
00151 else
00152 rrec->repeat_interval = 1;
00153 rrec->repeat_count = 3;
00154 rrec->repeat_time = time(NULL) + rrec->repeat_interval;
00155
00156
00157 rrec->in_expiration_processing = False;
00158
00159
00160 p->locked = True;
00161
00162 add_response_record(subrec, rrec);
00163
00164 return rrec;
00165 }
00166
00167
00168
00169
00170
00171 static struct response_record *find_response_record_on_subnet(
00172 struct subnet_record *subrec, uint16 id)
00173 {
00174 struct response_record *rrec = NULL;
00175
00176 for (rrec = subrec->responselist; rrec; rrec = rrec->next) {
00177 if (rrec->response_id == id) {
00178 DEBUG(4, ("find_response_record: found response record id = %hu on subnet %s\n",
00179 id, subrec->subnet_name));
00180 break;
00181 }
00182 }
00183 return rrec;
00184 }
00185
00186
00187
00188
00189
00190 struct response_record *find_response_record(struct subnet_record **ppsubrec,
00191 uint16 id)
00192 {
00193 struct response_record *rrec = NULL;
00194
00195 for ((*ppsubrec) = FIRST_SUBNET; (*ppsubrec);
00196 (*ppsubrec) = NEXT_SUBNET_INCLUDING_UNICAST(*ppsubrec)) {
00197 if((rrec = find_response_record_on_subnet(*ppsubrec, id)) != NULL)
00198 return rrec;
00199 }
00200
00201
00202
00203 if(remote_broadcast_subnet->responselist != NULL) {
00204 DEBUG(0,("find_response_record: response record found on subnet %s. This should \
00205 never happen !\n", remote_broadcast_subnet->subnet_name));
00206 }
00207
00208
00209 if(wins_server_subnet != NULL) {
00210 *ppsubrec = wins_server_subnet;
00211 if((rrec = find_response_record_on_subnet(*ppsubrec, id))!= NULL)
00212 return rrec;
00213 }
00214
00215 DEBUG(3,("find_response_record: response packet id %hu received with no \
00216 matching record.\n", id));
00217
00218 *ppsubrec = NULL;
00219
00220 return NULL;
00221 }
00222
00223
00224
00225
00226
00227 BOOL is_refresh_already_queued(struct subnet_record *subrec, struct name_record *namerec)
00228 {
00229 struct response_record *rrec = NULL;
00230
00231 for (rrec = subrec->responselist; rrec; rrec = rrec->next) {
00232 struct packet_struct *p = rrec->packet;
00233 struct nmb_packet *nmb = &p->packet.nmb;
00234
00235 if((nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
00236 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9)) {
00237
00238 if(nmb_name_equal(&nmb->question.question_name, &namerec->name))
00239 return True;
00240 }
00241 }
00242
00243 return False;
00244 }