freelist[ freeptr++ ] = n;
}
+/* release a linkage and if appropriate tell the kernel */
+void unhook_and_rel_map(int n)
+{
+ struct link *s = & map[n];
+ if (s->flags & LINK_UNBIND) {
+ ksend(NE_UNHOOK);
+ s->flags &= ~LINK_UNBIND;
+ }
+ rel_map(n);
+}
+
/* initialize the free map of links */
void init_map( void )
{
int n;
for ( n = 0; n<NSOCKET; n++)
- rel_map( n );
+ freelist[ freeptr++ ] = n;
}
-
/* send or resend tcp data */
void send_tcp( struct link *s )
{
s->flags &= ~LINK_CLOSED;
s->flags |= LINK_SHUTW | LINK_DEAD;
ne.socket = s->socketn;
- rel_map( uip_conn->appstate );
+ unhook_and_rel_map( uip_conn->appstate );
ne.data = SS_CLOSED;
ksend(NE_NEWSTATE);
}
ne.ret = ECONNREFUSED;
ksende(NE_RESET);
s->flags |= LINK_DEAD;
- rel_map( uip_conn->appstate );
+ unhook_and_rel_map( uip_conn->appstate );
} else if (uip_timedout()) {
ne.ret = ETIMEDOUT;
ksende(NE_RESET);
s->flags |= LINK_DEAD;
- rel_map( uip_conn->appstate );
+ unhook_and_rel_map( uip_conn->appstate );
} else if ( uip_closed()) {
int e;
switch ( s->flags & (LINK_SHUTR | LINK_SHUTW) ){
break;
case LINK_SHUTR | LINK_SHUTW:
s->flags |= LINK_DEAD;
- rel_map( uip_conn->appstate );
+ unhook_and_rel_map( uip_conn->appstate );
return;
}
}
ne.data = SS_CLOSED;
ksend( NE_NEWSTATE );
/* release private link resource */
- rel_map( uip_raw_conn->appstate );
+ unhook_and_rel_map( uip_raw_conn->appstate );
s->flags |= LINK_DEAD;
uip_raw_remove( uip_raw_conn );
return;
int i = read( knet, &sm, sizeof(sm) );
int c;
- if ( i < 0 ){
+ if ( i < 0 && errno != EAGAIN) {
+ perror("knet read");
return 0;
}
else if ( i == sizeof( sm ) && (sm.sd.event & 127)){
conptr->appstate = sm.sd.lcn;
/* refactor: same as tcp action from connect event */
ne.data = SS_CONNECTED;
- ksend( NE_NEWSTATE );
+ ksend(NE_NEWSTATE);
break;
}
break; /* FIXME: handle unknown/unhandled sock types here */
+ case SS_DEAD:
case SS_CLOSED:
if ( sm.s.s_type == SOCKTYPE_UDP ){
uip_udp_remove(m->conn);
rel_map(m->lcn);
ne.data = SS_CLOSED;
- ksend( NE_NEWSTATE );
+ ksend(NE_UNHOOK);
+ break;
+ }
+ /* If the tcp session died before we ask, then
+ we respond with an immeidate unhook */
+ if ( m->flags & LINK_DEAD) {
+ ksend(NE_UNHOOK);
break;
}
+ /* If not then we ask for a notification and
+ kick the process off */
+ m->flags |= LINK_UNBIND;
if ( sm.s.s_type == SOCKTYPE_TCP )
activity |= (1 << c);
m->flags |= LINK_CLOSED;
#define LINK_OPEN 8 /* TCP connected onward */
#define LINK_DEAD 16 /* No longer exists to the kernel (may be live
internally to uIP still */
+#define LINK_UNBIND 32 /* The kernel wants netd to confirm this link is
+ dead and will receive no more messages */
uint8_t socketn; /* Kernel's socket no */
uint8_t lcn; /* Kernel's idea of lcn ???*/
struct uip_conn *conn; /* uIP's idea of lcn */
#define SS_CLOSEWAIT 9 /* Remote has closed */
#define SS_CLOSING 10 /* Protocol close in progress */
#define SS_CLOSED 11 /* Protocol layers done, not close()d */
+#define SS_DEAD 12
/* FIXME: need state for shutdown handling */
uint8_t s_data; /* Socket we are an accept() for */
uint8_t s_error;
#define SI_EOF 8 /* At EOF */
#define SI_THROTTLE 16 /* Transmit is throttled */
void *s_priv; /* Private pointer for lower layers */
+ void *s_ino;
};
#define NSOCKTYPE 3