| 22 |
|
* $Id$ |
| 23 |
|
*/ |
| 24 |
|
#include "stdinc.h" |
| 25 |
< |
#include "tools.h" |
| 25 |
> |
#include "list.h" |
| 26 |
|
#include "s_bsd.h" |
| 27 |
< |
#include "s_conf.h" |
| 27 |
> |
#include "conf.h" |
| 28 |
|
#include "s_serv.h" |
| 29 |
|
#include "client.h" |
| 30 |
– |
#include "common.h" |
| 30 |
|
#include "ircd.h" |
| 32 |
– |
#include "list.h" |
| 31 |
|
#include "parse.h" |
| 32 |
|
#include "fdlist.h" |
| 33 |
|
#include "packet.h" |
| 35 |
|
#include "memory.h" |
| 36 |
|
#include "hook.h" |
| 37 |
|
#include "send.h" |
| 38 |
< |
#include "irc_getnameinfo.h" |
| 38 |
> |
#include "s_misc.h" |
| 39 |
|
|
| 40 |
|
#define READBUF_SIZE 16384 |
| 41 |
|
|
| 42 |
|
struct Callback *iorecv_cb = NULL; |
| 45 |
– |
struct Callback *iorecvctrl_cb = NULL; |
| 43 |
|
|
| 44 |
|
static char readBuf[READBUF_SIZE]; |
| 45 |
|
static void client_dopacket(struct Client *, char *, size_t); |
| 163 |
|
client_dopacket(client_p, readBuf, dolen); |
| 164 |
|
} |
| 165 |
|
} |
| 166 |
< |
else if(IsClient(client_p)) |
| 166 |
> |
else if (IsClient(client_p)) |
| 167 |
|
{ |
| 168 |
< |
if (ConfigFileEntry.no_oper_flood && (IsOper(client_p) || IsCanFlood(client_p))) |
| 168 |
> |
if (ConfigFileEntry.no_oper_flood && (HasUMode(client_p, UMODE_OPER) || IsCanFlood(client_p))) |
| 169 |
|
{ |
| 170 |
|
if (ConfigFileEntry.true_no_oper_flood) |
| 171 |
|
checkflood = -1; |
| 271 |
|
} |
| 272 |
|
|
| 273 |
|
/* |
| 274 |
< |
* read_ctrl_packet - Read a 'packet' of data from a servlink control |
| 278 |
< |
* link and process it. |
| 274 |
> |
* iorecv_default - append a packet to the recvq dbuf |
| 275 |
|
*/ |
| 276 |
< |
void |
| 277 |
< |
read_ctrl_packet(fde_t *fd, void *data) |
| 276 |
> |
void * |
| 277 |
> |
iorecv_default(va_list args) |
| 278 |
|
{ |
| 279 |
< |
struct Client *server = data; |
| 280 |
< |
struct LocalUser *lserver = server->localClient; |
| 281 |
< |
struct SlinkRpl *reply; |
| 286 |
< |
int length = 0; |
| 287 |
< |
unsigned char tmp[2]; |
| 288 |
< |
unsigned char *len = tmp; |
| 289 |
< |
struct SlinkRplDef *replydef; |
| 290 |
< |
|
| 291 |
< |
assert(lserver != NULL); |
| 292 |
< |
|
| 293 |
< |
reply = &lserver->slinkrpl; |
| 294 |
< |
|
| 295 |
< |
if (IsDefunct(server)) |
| 296 |
< |
return; |
| 297 |
< |
|
| 298 |
< |
if (!reply->command) |
| 299 |
< |
{ |
| 300 |
< |
reply->gotdatalen = 0; |
| 301 |
< |
reply->readdata = 0; |
| 302 |
< |
reply->data = NULL; |
| 303 |
< |
|
| 304 |
< |
length = recv(fd->fd, tmp, 1, 0); |
| 305 |
< |
|
| 306 |
< |
if (length <= 0) |
| 307 |
< |
{ |
| 308 |
< |
if ((length == -1) && ignoreErrno(errno)) |
| 309 |
< |
goto nodata; |
| 310 |
< |
dead_link_on_read(server, length); |
| 311 |
< |
return; |
| 312 |
< |
} |
| 313 |
< |
reply->command = tmp[0]; |
| 314 |
< |
} |
| 315 |
< |
|
| 316 |
< |
for (replydef = slinkrpltab; replydef->handler; replydef++) |
| 317 |
< |
{ |
| 318 |
< |
if (replydef->replyid == (unsigned int)reply->command) |
| 319 |
< |
break; |
| 320 |
< |
} |
| 321 |
< |
|
| 322 |
< |
/* we should be able to trust a local slink process... |
| 323 |
< |
* and if it sends an invalid command, that's a bug.. */ |
| 324 |
< |
assert(replydef->handler); |
| 325 |
< |
|
| 326 |
< |
if ((replydef->flags & SLINKRPL_FLAG_DATA) && (reply->gotdatalen < 2)) |
| 327 |
< |
{ |
| 328 |
< |
/* we need a datalen u16 which we don't have yet... */ |
| 329 |
< |
length = recv(fd->fd, len, (2 - reply->gotdatalen), 0); |
| 330 |
< |
if (length <= 0) |
| 331 |
< |
{ |
| 332 |
< |
if ((length == -1) && ignoreErrno(errno)) |
| 333 |
< |
goto nodata; |
| 334 |
< |
dead_link_on_read(server, length); |
| 335 |
< |
return; |
| 336 |
< |
} |
| 337 |
< |
|
| 338 |
< |
if (reply->gotdatalen == 0) |
| 339 |
< |
{ |
| 340 |
< |
reply->datalen = *len << 8; |
| 341 |
< |
reply->gotdatalen++; |
| 342 |
< |
length--; |
| 343 |
< |
len++; |
| 344 |
< |
} |
| 345 |
< |
if (length && (reply->gotdatalen == 1)) |
| 346 |
< |
{ |
| 347 |
< |
reply->datalen |= *len; |
| 348 |
< |
reply->gotdatalen++; |
| 349 |
< |
if (reply->datalen > 0) |
| 350 |
< |
reply->data = MyMalloc(reply->datalen); |
| 351 |
< |
} |
| 352 |
< |
|
| 353 |
< |
if (reply->gotdatalen < 2) |
| 354 |
< |
return; /* wait for more data */ |
| 355 |
< |
} |
| 356 |
< |
|
| 357 |
< |
if (reply->readdata < reply->datalen) /* try to get any remaining data */ |
| 358 |
< |
{ |
| 359 |
< |
length = recv(fd->fd, (reply->data + reply->readdata), |
| 360 |
< |
(reply->datalen - reply->readdata), 0); |
| 361 |
< |
if (length <= 0) |
| 362 |
< |
{ |
| 363 |
< |
if ((length == -1) && ignoreErrno(errno)) |
| 364 |
< |
goto nodata; |
| 365 |
< |
dead_link_on_read(server, length); |
| 366 |
< |
return; |
| 367 |
< |
} |
| 368 |
< |
|
| 369 |
< |
reply->readdata += length; |
| 370 |
< |
if (reply->readdata < reply->datalen) |
| 371 |
< |
return; /* wait for more data */ |
| 372 |
< |
} |
| 373 |
< |
|
| 374 |
< |
execute_callback(iorecvctrl_cb, server, reply->command); |
| 375 |
< |
|
| 376 |
< |
/* we now have the command and any data, pass it off to the handler */ |
| 377 |
< |
(*replydef->handler)(reply->command, reply->datalen, reply->data, server); |
| 279 |
> |
struct Client *client_p = va_arg(args, struct Client *); |
| 280 |
> |
int length = va_arg(args, int); |
| 281 |
> |
char *buf = va_arg(args, char *); |
| 282 |
|
|
| 283 |
< |
/* reset SlinkRpl */ |
| 284 |
< |
if (reply->datalen > 0) |
| 381 |
< |
MyFree(reply->data); |
| 382 |
< |
reply->command = 0; |
| 383 |
< |
|
| 384 |
< |
if (IsDead(server)) |
| 385 |
< |
return; |
| 386 |
< |
|
| 387 |
< |
nodata: |
| 388 |
< |
/* If we get here, we need to register for another COMM_SELECT_READ */ |
| 389 |
< |
comm_setselect(fd, COMM_SELECT_READ, read_ctrl_packet, server, 0); |
| 283 |
> |
dbuf_put(&client_p->localClient->buf_recvq, buf, length); |
| 284 |
> |
return NULL; |
| 285 |
|
} |
| 286 |
|
|
| 287 |
|
/* |
| 321 |
|
errno = EWOULDBLOCK; |
| 322 |
|
case SSL_ERROR_SYSCALL: |
| 323 |
|
break; |
| 324 |
+ |
case SSL_ERROR_SSL: |
| 325 |
+ |
if (errno == EAGAIN) |
| 326 |
+ |
break; |
| 327 |
|
default: |
| 328 |
|
length = errno = 0; |
| 329 |
|
} |
| 332 |
|
#endif |
| 333 |
|
{ |
| 334 |
|
length = recv(fd->fd, readBuf, READBUF_SIZE, 0); |
| 437 |
– |
#ifdef _WIN32 |
| 438 |
– |
if (length < 0) |
| 439 |
– |
errno = WSAGetLastError(); |
| 440 |
– |
#endif |
| 335 |
|
} |
| 336 |
|
|
| 337 |
|
if (length <= 0) |
| 349 |
|
|
| 350 |
|
execute_callback(iorecv_cb, client_p, length, readBuf); |
| 351 |
|
|
| 352 |
< |
if (client_p->lasttime < CurrentTime) |
| 353 |
< |
client_p->lasttime = CurrentTime; |
| 354 |
< |
if (client_p->lasttime > client_p->since) |
| 355 |
< |
client_p->since = CurrentTime; |
| 352 |
> |
if (client_p->localClient->lasttime < CurrentTime) |
| 353 |
> |
client_p->localClient->lasttime = CurrentTime; |
| 354 |
> |
if (client_p->localClient->lasttime > client_p->localClient->since) |
| 355 |
> |
client_p->localClient->since = CurrentTime; |
| 356 |
|
ClearPingSent(client_p); |
| 357 |
|
|
| 464 |
– |
dbuf_put(&client_p->localClient->buf_recvq, readBuf, length); |
| 465 |
– |
|
| 358 |
|
/* Attempt to parse what we have */ |
| 359 |
|
parse_client_queued(client_p); |
| 360 |
|
|
| 362 |
|
return; |
| 363 |
|
|
| 364 |
|
/* Check to make sure we're not flooding */ |
| 473 |
– |
/* TBD - ConfigFileEntry.client_flood should be a size_t */ |
| 365 |
|
if (!(IsServer(client_p) || IsHandshake(client_p) || IsConnecting(client_p)) |
| 366 |
|
&& (dbuf_length(&client_p->localClient->buf_recvq) > |
| 367 |
< |
(unsigned int)ConfigFileEntry.client_flood)) |
| 367 |
> |
get_recvq(client_p))) |
| 368 |
|
{ |
| 369 |
< |
if (!(ConfigFileEntry.no_oper_flood && IsOper(client_p))) |
| 369 |
> |
if (!(ConfigFileEntry.no_oper_flood && HasUMode(client_p, UMODE_OPER))) |
| 370 |
|
{ |
| 371 |
|
exit_client(client_p, client_p, "Excess Flood"); |
| 372 |
|
return; |