There was a rather large problem where the socket for a fn
connection was stored in the fnetnode itself, and filenet.c had
opinions on clearing its data internally in killfnetnode, which
led to a number of consistency problems -- the code was ugly,
and the daemon would occasionally segfault if killfnetnode had
cleared sk->data prematurely for some reason.
Now, each fnet module takes care of the socket itself, so that
it is modified internally only. The code is much cleaner that
way.
void killfnetnode(struct fnetnode *fn)
{
fnetsetstate(fn, FNN_DEAD);
void killfnetnode(struct fnetnode *fn)
{
fnetsetstate(fn, FNN_DEAD);
- if(fn->sk != NULL)
- {
- fn->sk->close = 1;
- if(fn->sk->data == fn)
- {
- fn->sk->data = NULL;
- putfnetnode(fn);
- }
- putsock(fn->sk);
- fn->sk = NULL;
- }
+ if(fn->connected)
+ fn->fnet->kill(fn);
}
void getfnetnode(struct fnetnode *fn)
}
void getfnetnode(struct fnetnode *fn)
CBCHAINFREE(fn, fnetpeer_new);
CBCHAINFREE(fn, fnetpeer_del);
CBCHAINFREE(fn, fnetpeer_chdi);
CBCHAINFREE(fn, fnetpeer_new);
CBCHAINFREE(fn, fnetpeer_del);
CBCHAINFREE(fn, fnetpeer_chdi);
- if(fn->fnet->destroy != NULL)
+ if((fn->fnet->destroy != NULL) && fn->connected)
fn->fnet->destroy(fn);
while(fn->args != NULL)
freewcspair(fn->args, &fn->args);
fn->fnet->destroy(fn);
while(fn->args != NULL)
freewcspair(fn->args, &fn->args);
free(fn->pubid);
if(fn->name != NULL)
free(fn->name);
free(fn->pubid);
if(fn->name != NULL)
free(fn->name);
- if(fn->sk != NULL)
- putsock(fn->sk);
if(fn->owner != NULL)
free(fn->owner);
free(fn);
if(fn->owner != NULL)
free(fn->owner);
free(fn);
putfnetnode(data);
return;
}
putfnetnode(data);
return;
}
fnetsetstate(data, FNN_HS);
socksettos(sk, confgetint("fnet", "fntos"));
fnetsetstate(data, FNN_HS);
socksettos(sk, confgetint("fnet", "fntos"));
- data->fnet->connect(data);
+ data->fnet->connect(data, sk);
+ data->connected = 1;
}
static void resolvecb(struct sockaddr *addr, int addrlen, struct fnetnode *data)
}
static void resolvecb(struct sockaddr *addr, int addrlen, struct fnetnode *data)
- if(fn->fnet->setnick != NULL)
+ if((fn->fnet->setnick != NULL) && fn->connected)
ret = fn->fnet->setnick(fn, newnick);
else
ret = 0;
ret = fn->fnet->setnick(fn, newnick);
else
ret = 0;
int fnetsendchat(struct fnetnode *fn, int public, wchar_t *to, wchar_t *string)
{
int fnetsendchat(struct fnetnode *fn, int public, wchar_t *to, wchar_t *string)
{
- if(fn->fnet->sendchat == NULL)
+ if((fn->fnet->sendchat == NULL) || !fn->connected)
{
errno = ENOTSUP;
return(-1);
{
errno = ENOTSUP;
return(-1);
{
struct fnet *next;
wchar_t *name;
{
struct fnet *next;
wchar_t *name;
- void (*connect)(struct fnetnode *fn);
+ void (*connect)(struct fnetnode *fn, struct socket *sk);
void (*destroy)(struct fnetnode *fn);
void (*destroy)(struct fnetnode *fn);
+ void (*kill)(struct fnetnode *fn);
int (*setnick)(struct fnetnode *fn, wchar_t *newnick);
int (*reqconn)(struct fnetpeer *peer);
int (*sendchat)(struct fnetnode *fn, int public, wchar_t *to, wchar_t *string);
int (*setnick)(struct fnetnode *fn, wchar_t *newnick);
int (*reqconn)(struct fnetpeer *peer);
int (*sendchat)(struct fnetnode *fn, int public, wchar_t *to, wchar_t *string);
int state;
int linked;
int regstatus;
int state;
int linked;
int regstatus;
time_t srchwait, lastsrch;
wchar_t *name, *pubid;
wchar_t *mynick;
wchar_t *owner;
struct fnet *fnet;
time_t srchwait, lastsrch;
wchar_t *name, *pubid;
wchar_t *mynick;
wchar_t *owner;
struct fnet *fnet;
struct fnetpeerdatum *peerdata;
struct fnetpeer *peers;
struct wcspair *args;
struct fnetpeerdatum *peerdata;
struct fnetpeer *peers;
struct wcspair *args;
char *inbuf;
size_t inbufdata, inbufsize;
wchar_t *sid;
char *inbuf;
size_t inbufdata, inbufsize;
wchar_t *sid;
#define UNUSED
#endif
#define ADC_CMDCOM \
#define UNUSED
#endif
#define ADC_CMDCOM \
- struct socket *sk UNUSED = fn->sk; \
- struct adchub *hub UNUSED = fn->data;
+ struct adchub *hub UNUSED = fn->data; \
+ struct socket *sk UNUSED = hub->sk;
-static void hubconnect(struct fnetnode *fn)
+static void hubconnect(struct fnetnode *fn, struct socket *sk)
- fn->sk->readcb = (void (*)(struct socket *, void *))hubread;
- fn->sk->errcb = (void (*)(struct socket *, int, void *))huberr;
- fn->sk->data = fn;
- getfnetnode(fn);
+ getsock(hub->sk = sk);
+ sk->readcb = (void (*)(struct socket *, void *))hubread;
+ sk->errcb = (void (*)(struct socket *, int, void *))huberr;
+ sk->data = fn;
hub = smalloc(sizeof(*hub));
memset(hub, 0, sizeof(*hub));
hub = smalloc(sizeof(*hub));
memset(hub, 0, sizeof(*hub));
return;
}
fn->data = hub;
return;
}
fn->data = hub;
- sendadc(fn->sk, 0, L"HSUP", L"ADBASE", eoc, NULL);
+ sendadc(sk, 0, L"HSUP", L"ADBASE", eoc, NULL);
}
static void hubdestroy(struct fnetnode *fn)
{
struct adchub *hub;
}
static void hubdestroy(struct fnetnode *fn)
{
struct adchub *hub;
- if((hub = fn->data) == NULL)
- return;
iconv_close(hub->ich);
if(hub->inbuf != NULL)
free(hub->inbuf);
iconv_close(hub->ich);
if(hub->inbuf != NULL)
free(hub->inbuf);
+static void hubkill(struct fnetnode *fn)
+{
+ struct adchub *hub;
+
+ hub = fn->data;
+ hub->sk->close = 1;
+}
+
static int hubsetnick(struct fnetnode *fn, wchar_t *newnick)
{
return(0);
static int hubsetnick(struct fnetnode *fn, wchar_t *newnick)
{
return(0);
static struct fnet adcnet_store = {
.connect = hubconnect,
.destroy = hubdestroy,
static struct fnet adcnet_store = {
.connect = hubconnect,
.destroy = hubdestroy,
.setnick = hubsetnick,
.reqconn = hubreqconn,
.name = L"adc"
.setnick = hubsetnick,
.reqconn = hubreqconn,
.name = L"adc"
if((hub = fn->data) == NULL)
continue;
if((qcmd = ulqcmd(&hub->queue)) != NULL) {
if((hub = fn->data) == NULL)
continue;
if((qcmd = ulqcmd(&hub->queue)) != NULL) {
- if((fn->sk != NULL) && (fn->sk->state == SOCK_EST))
+ if((hub->sk != NULL) && (hub->sk->state == SOCK_EST))
dispatch(qcmd, fn);
freeqcmd(qcmd);
ret = 1;
dispatch(qcmd, fn);
freeqcmd(qcmd);
ret = 1;
char *inbuf;
size_t inbufdata, inbufsize;
struct qcommand *queue;
char *inbuf;
size_t inbufdata, inbufsize;
struct qcommand *queue;
goto out;
prefix = sprintf2("$SR %s ", hub->nativenick);
infix = sprintf2(" %i/%i\005", slotsleft(), confgetint("transfer", "slots"));
goto out;
prefix = sprintf2("$SR %s ", hub->nativenick);
infix = sprintf2(" %i/%i\005", slotsleft(), confgetint("transfer", "slots"));
- postfix = sprintf2(" (%s)\005%s|", formataddress(fn->sk->remote, fn->sk->remotelen), args + 4);
+ postfix = sprintf2(" (%s)\005%s|", formataddress(hub->sk->remote, hub->sk->remotelen), args + 4);
dsk = sk;
getsock(dsk);
} else {
dsk = sk;
getsock(dsk);
} else {
addr.sin_port = htons(atoi(p2));
prefix = sprintf2("$SR %s ", hub->nativenick);
infix = sprintf2(" %i/%i\005", slotsleft(), confgetint("transfer", "slots"));
addr.sin_port = htons(atoi(p2));
prefix = sprintf2("$SR %s ", hub->nativenick);
infix = sprintf2(" %i/%i\005", slotsleft(), confgetint("transfer", "slots"));
- postfix = sprintf2(" (%s)|", formataddress(fn->sk->remote, fn->sk->remotelen));
+ postfix = sprintf2(" (%s)|", formataddress(hub->sk->remote, hub->sk->remotelen));
netdgramconn(dsk = netdupsock(udpsock), (struct sockaddr *)&addr, sizeof(addr));
}
netdgramconn(dsk = netdupsock(udpsock), (struct sockaddr *)&addr, sizeof(addr));
}
return;
*p2 = 0;
p2 += 2;
return;
*p2 = 0;
p2 += 2;
- hubrecvchat(fn->sk, fn, p, p2);
+ hubrecvchat(hub->sk, fn, p, p2);
hubhandleaction(sk, fn, cmd, args);
}
hubhandleaction(sk, fn, cmd, args);
}
return(1); /* Shouldn't happen, of course, but who knows... */
if(tcpsock != NULL)
{
return(1); /* Shouldn't happen, of course, but who knows... */
if(tcpsock != NULL)
{
- sendctm(peer->fn->sk, mbsnick);
+ sendctm(hub->sk, mbsnick);
expectpeer(mbsnick, peer->fn);
} else {
expectpeer(mbsnick, peer->fn);
} else {
- qstrf(peer->fn->sk, "$RevConnectToMe %s %s|", hub->nativenick, mbsnick);
+ qstrf(hub->sk, "$RevConnectToMe %s %s|", hub->nativenick, mbsnick);
}
free(mbsnick);
return(0);
}
free(mbsnick);
return(0);
- qstrf(fn->sk, "<%s> %s|", hub->nativenick, mbsstring);
+ qstrf(hub->sk, "<%s> %s|", hub->nativenick, mbsstring);
- qstrf(fn->sk, "$To: %s From: %s $<%s> %s|", mbsto, hub->nativenick, hub->nativenick, mbsstring);
+ qstrf(hub->sk, "$To: %s From: %s $<%s> %s|", mbsto, hub->nativenick, hub->nativenick, mbsstring);
- qstrf(fn->sk, "$To: %s From: %s $<%s> %s|", mbsto, hub->nativenick, hub->nativenick, mbsstring);
+ qstrf(hub->sk, "$To: %s From: %s $<%s> %s|", mbsto, hub->nativenick, hub->nativenick, mbsstring);
}
free(mbsto);
free(mbsstring);
}
free(mbsto);
free(mbsstring);
struct hash *hash;
hub = fn->data;
struct hash *hash;
hub = fn->data;
- if((fn->state != FNN_EST) || (fn->sk == NULL) || (fn->sk->state != SOCK_EST))
+ if((fn->state != FNN_EST) || (hub->sk == NULL) || (hub->sk->state != SOCK_EST))
return(1);
list = findsexprstrs(srch->sexpr);
findsizelimit(srch->sexpr, &minsize, &maxsize);
return(1);
list = findsexprstrs(srch->sexpr);
findsizelimit(srch->sexpr, &minsize, &maxsize);
addtobuf(sstr, 0);
if(tcpsock != NULL)
{
addtobuf(sstr, 0);
if(tcpsock != NULL)
{
- if(sockgetremotename2(udpsock, fn->sk, &name, &namelen) < 0)
+ if(sockgetremotename2(udpsock, hub->sk, &name, &namelen) < 0)
{
flog(LOG_WARNING, "cannot get address of UDP socket");
} else {
{
flog(LOG_WARNING, "cannot get address of UDP socket");
} else {
- qstrf(fn->sk, "$Search %s %s|", formataddress(name, namelen), sstr);
+ qstrf(hub->sk, "$Search %s %s|", formataddress(name, namelen), sstr);
- qstrf(fn->sk, "$Search Hub:%s %s|", hub->nativenick, sstr);
+ qstrf(hub->sk, "$Search Hub:%s %s|", hub->nativenick, sstr);
}
free(sstr);
freesl(&list);
}
free(sstr);
freesl(&list);
{
for(fn = fnetnodes; fn != NULL; fn = fn->next)
{
{
for(fn = fnetnodes; fn != NULL; fn = fn->next)
{
- if((fn->fnet == &dcnet) && (fn->sk != NULL) && addreq(fn->sk->remote, (struct sockaddr *)&hubaddr))
+ if((fn->fnet == &dcnet) && ((hub = fn->data) != NULL))
+ if((hub->sk != NULL) && addreq(hub->sk->remote, (struct sockaddr *)&hubaddr))
+ {
+ myfn = fn;
+ break;
+ }
-static void hubconnect(struct fnetnode *fn)
+static void hubconnect(struct fnetnode *fn, struct socket *sk)
- fn->sk->readcb = (void (*)(struct socket *, void *))hubread;
- fn->sk->errcb = (void (*)(struct socket *, int, void *))huberr;
- getfnetnode(fn);
- fn->data = newdchub(fn);
- fn->sk->data = fn;
+ struct dchub *hub;
+
+ sk->readcb = (void (*)(struct socket *, void *))hubread;
+ sk->errcb = (void (*)(struct socket *, int, void *))huberr;
+ fn->data = hub = newdchub(fn);
+ sk->data = fn;
+ getsock(hub->sk = sk);
struct qcommand *qcmd;
hub = (struct dchub *)fn->data;
struct qcommand *qcmd;
hub = (struct dchub *)fn->data;
- if((fn->sk != NULL) && (fn->sk->data == fn))
- {
- fn->sk->data = NULL;
- fn->sk->readcb = NULL;
- fn->sk->errcb = NULL;
- putfnetnode(fn);
- }
- if(hub == NULL)
- return;
while((qcmd = ulqcmd(&hub->queue)) != NULL)
freeqcmd(qcmd);
if(hub->supports != NULL)
while((qcmd = ulqcmd(&hub->queue)) != NULL)
freeqcmd(qcmd);
if(hub->supports != NULL)
+static void hubkill(struct fnetnode *fn)
+{
+ struct dchub *hub;
+
+ hub = (struct dchub *)fn->data;
+ hub->sk->close = 1;
+}
+
static wchar_t *dcbasename(wchar_t *filename)
{
wchar_t *ret;
static wchar_t *dcbasename(wchar_t *filename)
{
wchar_t *ret;
.name = L"dc",
.connect = hubconnect,
.destroy = hubdestroy,
.name = L"dc",
.connect = hubconnect,
.destroy = hubdestroy,
.setnick = hubsetnick,
.reqconn = hubreqconn,
.sendchat = hubsendchat,
.setnick = hubsetnick,
.reqconn = hubreqconn,
.sendchat = hubsendchat,
{
if(*qcmd->string == '$')
{
{
if(*qcmd->string == '$')
{
- if((fn->sk != NULL) && (fn->sk->state == SOCK_EST))
- dispatchcommand(qcmd, hubcmds, fn->sk, fn);
+ if((hub->sk != NULL) && (hub->sk->state == SOCK_EST))
+ dispatchcommand(qcmd, hubcmds, hub->sk, fn);
} else if(*qcmd->string != 0) {
} else if(*qcmd->string != 0) {
- hubrecvchat(fn->sk, fn, NULL, qcmd->string);
+ hubrecvchat(hub->sk, fn, NULL, qcmd->string);
}
freeqcmd(qcmd);
ret = 1;
}
freeqcmd(qcmd);
ret = 1;