Changeset 740 for vendor/current/libcli/nbt/namerefresh.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/libcli/nbt/namerefresh.c
r414 r740 21 21 22 22 #include "includes.h" 23 #include <tevent.h> 23 24 #include "../libcli/nbt/libnbt.h" 24 25 #include "../libcli/nbt/nbt_proto.h" 25 #include "libcli/composite/composite.h"26 26 #include "lib/socket/socket.h" 27 #include "lib/util/tevent_ntstatus.h" 27 28 28 29 /* … … 143 144 reply for each address 144 145 */ 145 struct refresh_wins_state {146 struct nbt_name_refresh_wins_state { 146 147 struct nbt_name_socket *nbtsock; 147 148 struct nbt_name_refresh *io; 148 c onst char **wins_servers;149 char **wins_servers; 149 150 uint16_t wins_port; 150 c onst char **addresses;151 char **addresses; 151 152 int address_idx; 152 struct nbt_name_request *req;153 153 }; 154 154 155 156 /** 157 state handler for WINS multi-homed multi-server name refresh 158 */ 159 static void name_refresh_wins_handler(struct nbt_name_request *req) 160 { 161 struct composite_context *c = talloc_get_type(req->async.private_data, 162 struct composite_context); 163 struct refresh_wins_state *state = talloc_get_type(c->private_data, 164 struct refresh_wins_state); 165 NTSTATUS status; 166 167 status = nbt_name_refresh_recv(state->req, state, state->io); 168 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { 169 /* the refresh timed out - try the next WINS server */ 170 state->wins_servers++; 171 state->address_idx = 0; 172 if (state->wins_servers[0] == NULL) { 173 c->state = COMPOSITE_STATE_ERROR; 174 c->status = status; 175 goto done; 176 } 177 state->io->in.dest_addr = state->wins_servers[0]; 178 state->io->in.dest_port = state->wins_port; 179 state->io->in.address = state->addresses[0]; 180 state->req = nbt_name_refresh_send(state->nbtsock, state->io); 181 if (state->req == NULL) { 182 c->state = COMPOSITE_STATE_ERROR; 183 c->status = NT_STATUS_NO_MEMORY; 184 } else { 185 state->req->async.fn = name_refresh_wins_handler; 186 state->req->async.private_data = c; 187 } 188 } else if (!NT_STATUS_IS_OK(status)) { 189 c->state = COMPOSITE_STATE_ERROR; 190 c->status = status; 191 } else { 192 if (state->io->out.rcode == 0 && 193 state->addresses[state->address_idx+1] != NULL) { 194 /* refresh our next address */ 195 state->io->in.address = state->addresses[++(state->address_idx)]; 196 state->req = nbt_name_refresh_send(state->nbtsock, state->io); 197 if (state->req == NULL) { 198 c->state = COMPOSITE_STATE_ERROR; 199 c->status = NT_STATUS_NO_MEMORY; 200 } else { 201 state->req->async.fn = name_refresh_wins_handler; 202 state->req->async.private_data = c; 203 } 204 } else { 205 c->state = COMPOSITE_STATE_DONE; 206 c->status = NT_STATUS_OK; 207 } 208 } 209 210 done: 211 if (c->state >= COMPOSITE_STATE_DONE && 212 c->async.fn) { 213 c->async.fn(c); 214 } 215 } 155 static void nbt_name_refresh_wins_handler(struct nbt_name_request *subreq); 216 156 217 157 /** 218 158 the async send call for a multi-server WINS refresh 219 159 */ 220 _PUBLIC_ struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbtsock, 221 struct nbt_name_refresh_wins *io) 222 { 223 struct composite_context *c; 224 struct refresh_wins_state *state; 225 226 c = talloc_zero(nbtsock, struct composite_context); 227 if (c == NULL) goto failed; 228 229 state = talloc(c, struct refresh_wins_state); 230 if (state == NULL) goto failed; 160 _PUBLIC_ struct tevent_req *nbt_name_refresh_wins_send(TALLOC_CTX *mem_ctx, 161 struct tevent_context *ev, 162 struct nbt_name_socket *nbtsock, 163 struct nbt_name_refresh_wins *io) 164 { 165 struct tevent_req *req; 166 struct nbt_name_refresh_wins_state *state; 167 struct nbt_name_request *subreq; 168 169 req = tevent_req_create(mem_ctx, &state, 170 struct nbt_name_refresh_wins_state); 171 if (req == NULL) { 172 return NULL; 173 } 231 174 232 175 state->io = talloc(state, struct nbt_name_refresh); 233 if (state->io == NULL) goto failed; 176 if (tevent_req_nomem(state->io, req)) { 177 return tevent_req_post(req, ev); 178 } 179 180 if (io->in.wins_servers == NULL) { 181 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 182 return tevent_req_post(req, ev); 183 } 184 185 if (io->in.wins_servers[0] == NULL) { 186 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 187 return tevent_req_post(req, ev); 188 } 189 190 if (io->in.addresses == NULL) { 191 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 192 return tevent_req_post(req, ev); 193 } 194 195 if (io->in.addresses[0] == NULL) { 196 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 197 return tevent_req_post(req, ev); 198 } 234 199 235 200 state->wins_port = io->in.wins_port; 236 state->wins_servers = (const char **)str_list_copy(state, io->in.wins_servers); 237 if (state->wins_servers == NULL || 238 state->wins_servers[0] == NULL) goto failed; 239 240 state->addresses = (const char **)str_list_copy(state, io->in.addresses); 241 if (state->addresses == NULL || 242 state->addresses[0] == NULL) goto failed; 201 state->wins_servers = str_list_copy(state, io->in.wins_servers); 202 if (tevent_req_nomem(state->wins_servers, req)) { 203 return tevent_req_post(req, ev); 204 } 205 206 state->addresses = str_list_copy(state, io->in.addresses); 207 if (tevent_req_nomem(state->addresses, req)) { 208 return tevent_req_post(req, ev); 209 } 243 210 244 211 state->io->in.name = io->in.name; … … 255 222 state->address_idx = 0; 256 223 257 state->req = nbt_name_refresh_send(nbtsock, state->io); 258 if (state->req == NULL) goto failed; 259 260 state->req->async.fn = name_refresh_wins_handler; 261 state->req->async.private_data = c; 262 263 c->private_data = state; 264 c->state = COMPOSITE_STATE_IN_PROGRESS; 265 c->event_ctx = nbtsock->event_ctx; 266 267 return c; 268 269 failed: 270 talloc_free(c); 271 return NULL; 224 subreq = nbt_name_refresh_send(nbtsock, state->io); 225 if (tevent_req_nomem(subreq, req)) { 226 return tevent_req_post(req, ev); 227 } 228 229 subreq->async.fn = nbt_name_refresh_wins_handler; 230 subreq->async.private_data = req; 231 232 return req; 233 } 234 235 static void nbt_name_refresh_wins_handler(struct nbt_name_request *subreq) 236 { 237 struct tevent_req *req = 238 talloc_get_type_abort(subreq->async.private_data, 239 struct tevent_req); 240 struct nbt_name_refresh_wins_state *state = 241 tevent_req_data(req, 242 struct nbt_name_refresh_wins_state); 243 NTSTATUS status; 244 245 status = nbt_name_refresh_recv(subreq, state, state->io); 246 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { 247 /* the refresh timed out - try the next WINS server */ 248 state->wins_servers++; 249 if (state->wins_servers[0] == NULL) { 250 tevent_req_nterror(req, status); 251 return; 252 } 253 254 state->address_idx = 0; 255 state->io->in.dest_addr = state->wins_servers[0]; 256 state->io->in.dest_port = state->wins_port; 257 state->io->in.address = state->addresses[0]; 258 259 subreq = nbt_name_refresh_send(state->nbtsock, state->io); 260 if (tevent_req_nomem(subreq, req)) { 261 return; 262 } 263 subreq->async.fn = nbt_name_refresh_wins_handler; 264 subreq->async.private_data = req; 265 } else if (!NT_STATUS_IS_OK(status)) { 266 tevent_req_nterror(req, status); 267 return; 268 } 269 270 if (state->io->out.rcode == 0 && 271 state->addresses[state->address_idx+1] != NULL) { 272 /* refresh our next address */ 273 state->io->in.address = state->addresses[++(state->address_idx)]; 274 subreq = nbt_name_refresh_send(state->nbtsock, state->io); 275 if (tevent_req_nomem(subreq, req)) { 276 return; 277 } 278 subreq->async.fn = nbt_name_refresh_wins_handler; 279 subreq->async.private_data = req; 280 return; 281 } 282 283 tevent_req_done(req); 272 284 } 273 285 … … 275 287 multi-homed WINS name refresh - recv side 276 288 */ 277 _PUBLIC_ NTSTATUS nbt_name_refresh_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, 278 struct nbt_name_refresh_wins *io) 279 { 289 _PUBLIC_ NTSTATUS nbt_name_refresh_wins_recv(struct tevent_req *req, 290 TALLOC_CTX *mem_ctx, 291 struct nbt_name_refresh_wins *io) 292 { 293 struct nbt_name_refresh_wins_state *state = 294 tevent_req_data(req, 295 struct nbt_name_refresh_wins_state); 280 296 NTSTATUS status; 281 status = composite_wait(c); 282 if (NT_STATUS_IS_OK(status)) { 283 struct refresh_wins_state *state = 284 talloc_get_type(c->private_data, struct refresh_wins_state); 285 io->out.wins_server = talloc_steal(mem_ctx, state->wins_servers[0]); 286 io->out.rcode = state->io->out.rcode; 287 } 288 talloc_free(c); 289 return status; 297 298 if (tevent_req_is_nterror(req, &status)) { 299 tevent_req_received(req); 300 return status; 301 } 302 303 io->out.wins_server = talloc_move(mem_ctx, &state->wins_servers[0]); 304 io->out.rcode = state->io->out.rcode; 305 306 tevent_req_received(req); 307 return NT_STATUS_OK; 290 308 } 291 309 … … 294 312 */ 295 313 _PUBLIC_ NTSTATUS nbt_name_refresh_wins(struct nbt_name_socket *nbtsock, 296 TALLOC_CTX *mem_ctx, 297 struct nbt_name_refresh_wins *io) 298 { 299 struct composite_context *c = nbt_name_refresh_wins_send(nbtsock, io); 300 return nbt_name_refresh_wins_recv(c, mem_ctx, io); 301 } 314 TALLOC_CTX *mem_ctx, 315 struct nbt_name_refresh_wins *io) 316 { 317 TALLOC_CTX *frame = talloc_stackframe(); 318 struct tevent_context *ev; 319 struct tevent_req *subreq; 320 NTSTATUS status; 321 322 /* 323 * TODO: create a temporary event context 324 */ 325 ev = nbtsock->event_ctx; 326 327 subreq = nbt_name_refresh_wins_send(frame, ev, nbtsock, io); 328 if (subreq == NULL) { 329 talloc_free(frame); 330 return NT_STATUS_NO_MEMORY; 331 } 332 333 if (!tevent_req_poll(subreq, ev)) { 334 status = map_nt_error_from_unix(errno); 335 talloc_free(frame); 336 return status; 337 } 338 339 status = nbt_name_refresh_wins_recv(subreq, mem_ctx, io); 340 if (!NT_STATUS_IS_OK(status)) { 341 talloc_free(frame); 342 return status; 343 } 344 345 TALLOC_FREE(frame); 346 return NT_STATUS_OK; 347 }
Note:
See TracChangeset
for help on using the changeset viewer.