Пример #1
0
static int ioctl_delete(ITF *itf,uint32_t ip,int flags)
{
    ENTRY *entry,*walk,*next;

    if (!(entry = lookup_ip(itf,ip))) {
	diag(COMPONENT,DIAG_WARN,"ioctl_delete didn't find entry");
	return -ENOENT;
    }
    if ((flags ^ entry->flags) & ATF_ARPSRV) return -EINVAL;
    send_notifications(entry,0);
    if ((entry->flags & ATF_ARPSRV) && entry->itf)
	for (walk = entry->itf->table; walk; walk = next) {
	    next = walk->next;
	    if (walk != entry && walk->state == as_resolv) {
		send_notifications(walk,0);
		if (!walk->vccs && !(walk->flags & ATF_PERM))
		   /* PERM is rather unlikely here, since this would be a
		      second ARP server (only ARP servers can go as_resolv if
		      PERM), but we'll check for it anyway. */
		    discard_entry(walk);
		else {
		    STOP_TIMER(walk);
		    walk->state = as_invalid;
		}
	    }
	}
    discard_entry(entry);
    return 0;
}
Пример #2
0
static void timeout(ENTRY *entry)
{
    VCC *vcc,*next;

    entry->timer = NULL;
    switch (entry->state) {
	case as_resolv:
	    send_notifications(entry,0);
	    if ((entry->flags & ATF_ARPSRV) && !entry->vccs) {
		if (entry->itf) want_arp_srv(entry->itf);
		break;
	    }
	    if (!entry->vccs && !(entry->flags & (ATF_PERM | ATF_ARPSRV)))
		discard_entry(entry);
	    else entry->state = as_invalid;
	    break;
	case as_valid:
	    if (!entry->vccs && !(entry->flags & (ATF_PERM | ATF_ARPSRV)) &&
	      entry->itf->arp_srv) {
		discard_entry(entry);
		break;
	    }
	    for (vcc = entry->vccs; vcc; vcc = next) {
		next = vcc->next;
		if (!vcc->connecting)
		    if (set_ip(vcc->fd,0) < 0) {
			diag(COMPONENT,DIAG_ERROR,"set_ip(0): %s",
			  strerror(errno));
			disconnect_vcc(vcc);
		    }
	    }
	    if (entry->svc && entry->itf->arp_srv &&
	      !(entry->flags & ATF_ARPSRV)) revalidate(entry);
	    else {
		inarp_request(entry);
		START_TIMER(entry,REPLY);
		entry->state = as_invalid;
	    }
	    break;
	case as_invalid:
	    if (!entry->svc) {
		inarp_request(entry);
		START_TIMER(entry,REPLY);
	    }
	    else if ((!entry->itf || !entry->itf->arp_srv) &&
		  !(entry->flags & ATF_PERM)) discard_entry(entry);
	    break;
	default:
	    diag(COMPONENT,DIAG_FATAL,"timed out in state %s",
	      entry_state_name[entry->state]);
    }
}
Пример #3
0
static void
test_discard_entry_no_response(void **state)
{
    struct entry *e;
    krb5_context context = *state;
    krb5_data req = string2data("I'm a test request");

    e = insert_entry(context, &req, NULL, 0);
    discard_entry(context, e);

    assert_null(k5_hashtab_get(hash_table, req.data, req.length));
    assert_int_equal(num_entries, 0);
    assert_int_equal(total_size, 0);
}
Пример #4
0
static void learn_nak(uint32_t ip)
{
    ITF *itf;
    ENTRY *entry;

    if (!ip) return;
    itf = lookup_itf_by_ip(ip);
    if (!itf) return;
    entry = lookup_ip(itf,ip);
    if (!entry || entry->state != as_resolv) return;
    send_notifications(entry,0);
    if (entry->flags & ATF_PERM) return;
    if (entry->vccs) entry->state = as_invalid;
    else discard_entry(entry);
}
Пример #5
0
void vcc_detach(ENTRY *entry)
{
    ENTRY *walk;

    /* immediately try to bring it up again if this was the connection to the
       ATMARP server and we still need it. Should delay this in case the ARP
       server has a real problem. @@@ */
    /* UPDATE: the delay might work now ... */
    if (entry->itf && entry->itf->arp_srv == entry)
	for (walk = entry->itf->table; walk; walk = walk->next) {
	    if (walk->state == as_resolv) break;
	if (walk) {
	    if (entry->state == as_valid) START_TIMER(entry,REGISTER);
	    /* (void) want_arp_srv(entry->itf); */
	    return;
	}
    }
    if (!entry->vccs && entry->state == as_invalid && !(entry->flags &
      ATF_PERM)) discard_entry(entry);
}
Пример #6
0
void vcc_failed(VCC *vcc)
{
    ENTRY *entry,*next;

    diag(COMPONENT,DIAG_DEBUG,"failed VCC 0x%p",vcc);
    Q_REMOVE(vcc->entry->vccs,vcc);
    if (!(vcc->entry->flags & ATF_ARPSRV) || vcc->entry->vccs) {
	/* VCC is already closed */
	vcc_detach(vcc->entry);
	free(vcc);
	return;
    }
    for (entry = vcc->entry->itf->table; entry; entry = next) {
	next = entry->next;
	if (entry == vcc->entry || entry->state != as_resolv) continue;
	if (entry->vccs || (entry->flags & ATF_PERM)) entry->state = as_invalid;
	else discard_entry(entry);
    }
    START_TIMER(vcc->entry,RETRY);
    free(vcc);
}