ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/branches/newio/src/s_bsd.c
(Generate patch)

Comparing branches/newio/src/s_bsd.c (file contents):
Revision 2391 by michael, Thu Jul 11 20:57:08 2013 UTC vs.
Revision 2392 by michael, Sat Jul 13 22:13:28 2013 UTC

# Line 28 | Line 28
28   #include <netinet/ip.h>
29   #include <netinet/tcp.h>
30   #include "list.h"
31 #include "fdlist.h"
31   #include "s_bsd.h"
32   #include "client.h"
33   #include "dbuf.h"
35 #include "event.h"
34   #include "irc_string.h"
35   #include "ircd.h"
36   #include "listener.h"
# Line 48 | Line 46
46   #include "memory.h"
47   #include "s_user.h"
48   #include "msgq.h"
49 + #include "ioengine.h"
50  
51  
52   dlink_list connection_list;
# Line 240 | Line 239 | os_recvfrom_nonb(int fd, char *buf, unsi
239  
240    if (res > -1)
241    {
242 <    *length_out = res;
242 >    *length_out = (unsigned int)res;
243      return IO_SUCCESS;
244    }
245  
# Line 266 | Line 265 | os_send_nonb(int fd, const char *buf, un
265  
266    if ((res = send(fd, buf, length, 0)) > -1)
267    {
268 <    *count_out = (unsigned) res;
268 >    *count_out = (unsigned int)res;
269      return IO_SUCCESS;
270    }
271  
# Line 305 | Line 304 | os_sendv_nonb(int fd, struct MsgQ *buf,
304    return is_blocked(errno) ? IO_BLOCKED : IO_FAILURE;
305   }
306  
307 + /** Attempt to write on a non-blocking UDP socket.
308 + * @param[in] fd File descriptor to write to.
309 + * @param[in] buf Output buffer to send from.
310 + * @param[in] length Number of bytes to write.
311 + * @param[out] count_out Receives number of bytes actually written.
312 + * @param[in] flags Flags for call to sendto().
313 + * @param[in] peer Destination address of the message.
314 + * @return An IOResult value indicating status.
315 + */
316 + IOResult os_sendto_nonb(int fd, const char *buf, unsigned int length,
317 +                        unsigned int *count_out, unsigned int flags,
318 +                        struct irc_ssaddr *peer)
319 + {
320 +  int res = 0, size = 0;
321 +
322 +  assert(buf);
323 +
324 +  if ((res = sendto(fd, buf, length, flags, (struct sockaddr *)&peer, peer->ss_len)) > -1)
325 +  {
326 +    if (count_out)
327 +      *count_out = (unsigned int)res;
328 +    return IO_SUCCESS;
329 +  }
330 +
331 +  if (count_out)
332 +    *count_out = 0;
333 +  return is_blocked(errno) ? IO_BLOCKED : IO_FAILURE;
334 + }
335 +
336 + /** Start a non-blocking connection.
337 + * @param[in] fd Disconnected file descriptor.
338 + * @param[in] sin Target address for connection.
339 + * @return IOResult code indicating status.
340 + */
341 + IOResult os_connect_nonb(int fd, const struct irc_ssaddr *addr)
342 + {
343 +  int size;
344 +
345 +  size = sockaddr_from_irc(&addr, sin, fd);
346 +  if (connect(fd, (struct sockaddr*) &addr, size))
347 +    return (errno == EINPROGRESS) ? IO_BLOCKED : IO_FAILURE;
348 +  return IO_SUCCESS;
349 + }
350 +
351 + int
352 + os_accept(int fd, struct irc_ssaddr *addr)
353 + {
354 +  int new_fd = 0;
355 +  socklen_t addrlen = sizeof(struct irc_ssaddr);
356 +
357 +  new_fd = accept(fd, (struct sockaddr *)addr, &addrlen);
358 +  if (new_fd < 0)
359 +    return -1;
360 +
361 + #ifdef IPV6
362 +  remove_ipv6_mapping(addr);
363 + #else
364 +  addr->ss_len = addrlen;
365 + #endif
366 +  setup_socket(new_fd);
367 +  return new_fd;
368 + }
369 +
370 + int
371 + os_socket(int family, int sock_type, int proto)
372 + {
373 +  int fd;
374 +
375 +  fd = socket(family, sock_type, proto);
376 +  if (fd < 0)
377 +    return -1;
378 +  setup_socket(fd);
379 +  return fd;
380 + }
381 +
382   /*
383   * report_error - report an error from an errno.
384   * Record error to log and also send a copy to all *LOCAL* opers online.
# Line 853 | Line 927 | comm_setflush(fde_t *fd, time_t timeout,
927   }
928  
929   /*
856 * comm_checktimeouts() - check the socket timeouts
857 *
858 * All this routine does is call the given callback/cbdata, without closing
859 * down the file descriptor. When close handlers have been implemented,
860 * this will happen.
861 */
862 void
863 comm_checktimeouts(void *notused)
864 {
865  int i;
866  fde_t *F;
867  PF *hdl;
868  void *data;
869
870  for (i = 0; i < FD_HASH_SIZE; i++)
871    for (F = fd_hash[i]; F != NULL; F = fd_next_in_loop)
872    {
873      assert(F->flags.open);
874      fd_next_in_loop = F->hnext;
875
876      /* check flush functions */
877      if (F->flush_handler && F->flush_timeout > 0 &&
878          F->flush_timeout < CurrentTime)
879      {
880        hdl = F->flush_handler;
881        data = F->flush_data;
882        comm_setflush(F, 0, NULL, NULL);
883        hdl(F, data);
884      }
885
886      /* check timeouts */
887      if (F->timeout_handler && F->timeout > 0 &&
888          F->timeout < CurrentTime)
889      {
890        /* Call timeout handler */
891        hdl = F->timeout_handler;
892        data = F->timeout_data;
893        comm_settimeout(F, 0, NULL, NULL);
894        hdl(F, data);
895      }
896    }
897 }
898
899 /*
930   * void comm_connect_tcp(int fd, const char *host, unsigned short port,
931   *                       struct sockaddr *clocal, int socklen,
932   *                       CNCB *callback, void *data, int aftype, int timeout)
# Line 1098 | Line 1128 | comm_errstr(int error)
1128    return comm_err_str[error];
1129   }
1130  
1101 /*
1102 * comm_open() - open a socket
1103 *
1104 * This is a highly highly cut down version of squid's comm_open() which
1105 * for the most part emulates socket(), *EXCEPT* it fails if we're about
1106 * to run out of file descriptors.
1107 */
1108 int
1109 comm_open(fde_t *F, int family, int sock_type, int proto, const char *note)
1110 {
1111  int fd;
1112
1113  /* First, make sure we aren't going to run out of file descriptors */
1114  if (number_fd >= hard_fdlimit)
1115  {
1116    errno = ENFILE;
1117    return -1;
1118  }
1119
1120  /*
1121   * Next, we try to open the socket. We *should* drop the reserved FD
1122   * limit if/when we get an error, but we can deal with that later.
1123   * XXX !!! -- adrian
1124   */
1125  fd = socket(family, sock_type, proto);
1126  if (fd < 0)
1127    return -1; /* errno will be passed through, yay.. */
1128
1129  setup_socket(fd);
1130
1131  /* update things in our fd tracking */
1132  fd_open(F, fd, 1, note);
1133  return 0;
1134 }
1135
1136 /*
1137 * comm_accept() - accept an incoming connection
1138 *
1139 * This is a simple wrapper for accept() which enforces FD limits like
1140 * comm_open() does. Returned fd must be either closed or tagged with
1141 * fd_open (this function no longer does it).
1142 */
1143 int
1144 comm_accept(struct Listener *lptr, struct irc_ssaddr *pn)
1145 {
1146  int newfd;
1147  socklen_t addrlen = sizeof(struct irc_ssaddr);
1148
1149  if (number_fd >= hard_fdlimit)
1150  {
1151    errno = ENFILE;
1152    return -1;
1153  }
1154
1155  /*
1156   * Next, do the accept(). if we get an error, we should drop the
1157   * reserved fd limit, but we can deal with that when comm_open()
1158   * also does it. XXX -- adrian
1159   */
1160  newfd = accept(lptr->fd.fd, (struct sockaddr *)pn, &addrlen);
1161  if (newfd < 0)
1162    return -1;
1163
1164 #ifdef IPV6
1165  remove_ipv6_mapping(pn);
1166 #else
1167  pn->ss_len = addrlen;
1168 #endif
1169
1170  execute_callback(setup_socket_cb, newfd);
1171
1172  /* .. and return */
1173  return newfd;
1174 }
1175
1131   /*
1132   * remove_ipv6_mapping() - Removes IPv4-In-IPv6 mapping from an address
1133   * OSes with IPv6 mapping listening on both

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)