Needed locking in getpeer_string().
Added mutex locking around the dnscache() call. Removed the global sockaddr and setup_fd variables. Added the socket_blocking() and socket_nonblocking() functions. Gutted the readling() function and replaced it with something similar to the 1.0 version. :)
This commit is contained in:
parent
c0ff35dd22
commit
f6b7fe3f5c
382
src/sock.c
382
src/sock.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: sock.c,v 1.2 2000-03-31 20:10:13 rjkaes Exp $
|
/* $Id: sock.c,v 1.3 2000-09-11 23:56:32 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* Sockets are created and destroyed here. When a new connection comes in from
|
* Sockets are created and destroyed here. When a new connection comes in from
|
||||||
* a client, we need to copy the socket and the create a second socket to the
|
* a client, we need to copy the socket and the create a second socket to the
|
||||||
@ -21,52 +21,45 @@
|
|||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <defines.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "tinyproxy.h"
|
#include "tinyproxy.h"
|
||||||
#include "sock.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "dnscache.h"
|
#include "dnscache.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "sock.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#define SA struct sockaddr
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The mutex is used for locking around the calls to the dnscache since I
|
||||||
|
* don't want multiple threads accessing the linked list at the same time.
|
||||||
|
* This should be more fine grained, but it will do for now.
|
||||||
|
* - rjkaes
|
||||||
|
*/
|
||||||
|
pthread_mutex_t sock_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
#define SOCK_LOCK() pthread_mutex_lock(&sock_mutex);
|
||||||
|
#define SOCK_UNLOCK() pthread_mutex_unlock(&sock_mutex);
|
||||||
|
|
||||||
|
|
||||||
/* This routine is so old I can't even remember writing it. But I do
|
/* This routine is so old I can't even remember writing it. But I do
|
||||||
* remember that it was an .h file because I didn't know putting code in a
|
* remember that it was an .h file because I didn't know putting code in a
|
||||||
* header was bad magic yet. anyway, this routine opens a connection to a
|
* header was bad magic yet. anyway, this routine opens a connection to a
|
||||||
* system and returns the fd.
|
* system and returns the fd.
|
||||||
*/
|
* - steve
|
||||||
|
*
|
||||||
/*
|
|
||||||
* Cleaned up some of the code to use memory routines which are now the
|
* Cleaned up some of the code to use memory routines which are now the
|
||||||
* default. Also, the routine first checks to see if the address is in
|
* default. Also, the routine first checks to see if the address is in
|
||||||
* dotted-decimal form before it does a name lookup. Finally, the newly
|
* dotted-decimal form before it does a name lookup.
|
||||||
* created socket is made non-blocking.
|
|
||||||
* - rjkaes
|
* - rjkaes
|
||||||
*/
|
*/
|
||||||
int opensock(char *ip_addr, int port)
|
int opensock(char *ip_addr, int port)
|
||||||
{
|
{
|
||||||
int sock_fd, flags;
|
int sock_fd;
|
||||||
struct sockaddr_in port_info;
|
struct sockaddr_in port_info;
|
||||||
|
int ret;
|
||||||
|
|
||||||
assert(ip_addr);
|
memset((SA *) &port_info, 0, sizeof(port_info));
|
||||||
assert(port > 0);
|
|
||||||
|
|
||||||
memset((struct sockaddr *) &port_info, 0, sizeof(port_info));
|
|
||||||
|
|
||||||
port_info.sin_family = AF_INET;
|
port_info.sin_family = AF_INET;
|
||||||
|
|
||||||
@ -74,145 +67,84 @@ int opensock(char *ip_addr, int port)
|
|||||||
* before a non-blocking DNS query happens for this address. Not
|
* before a non-blocking DNS query happens for this address. Not
|
||||||
* relevant in the code as it stands.
|
* relevant in the code as it stands.
|
||||||
*/
|
*/
|
||||||
if (dnscache(&port_info.sin_addr, ip_addr) < 0) {
|
SOCK_LOCK();
|
||||||
log("ERROR opensock: Could not lookup address: %s", ip_addr);
|
ret = dnscache(&port_info.sin_addr, ip_addr);
|
||||||
|
SOCK_UNLOCK();
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
log(LOG_ERR, "opensock: Could not lookup address: %s", ip_addr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
port_info.sin_port = htons(port);
|
port_info.sin_port = htons(port);
|
||||||
|
|
||||||
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
|
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
|
||||||
log("ERROR opensock: socket (%s)", strerror(errno));
|
log(LOG_ERR, "opensock: socket (%s)", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = fcntl(sock_fd, F_GETFL, 0);
|
if (connect(sock_fd, (SA *) &port_info, sizeof(port_info)) < 0) {
|
||||||
fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK);
|
log(LOG_ERR, "connecting socket");
|
||||||
|
|
||||||
if (connect
|
|
||||||
(sock_fd, (struct sockaddr *) &port_info, sizeof(port_info)) < 0) {
|
|
||||||
if (errno != EINPROGRESS) {
|
|
||||||
log("ERROR opensock: connect (%s)", strerror(errno));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return sock_fd;
|
return sock_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* chris - added this to open a socket given a struct in_addr */
|
|
||||||
int opensock_inaddr(struct in_addr *inaddr, int port)
|
|
||||||
{
|
|
||||||
int sock_fd, flags;
|
|
||||||
struct sockaddr_in port_info;
|
|
||||||
|
|
||||||
assert(inaddr);
|
|
||||||
assert(port > 0);
|
|
||||||
|
|
||||||
memset((struct sockaddr *) &port_info, 0, sizeof(port_info));
|
|
||||||
|
|
||||||
port_info.sin_family = AF_INET;
|
|
||||||
|
|
||||||
memcpy(&port_info.sin_addr, inaddr, sizeof(struct in_addr));
|
|
||||||
|
|
||||||
port_info.sin_port = htons(port);
|
|
||||||
|
|
||||||
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
|
|
||||||
log("ERROR opensock_inaddr: socket (%s)", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
flags = fcntl(sock_fd, F_GETFL, 0);
|
|
||||||
fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK);
|
|
||||||
|
|
||||||
if (connect
|
|
||||||
(sock_fd, (struct sockaddr *) &port_info, sizeof(port_info)) < 0) {
|
|
||||||
if (errno != EINPROGRESS) {
|
|
||||||
log("ERROR opensock: connect (%s)", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sock_fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
int setup_fd;
|
|
||||||
static struct sockaddr listen_sock_addr;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start listening to a socket.
|
* Set the socket to non blocking -rjkaes
|
||||||
*/
|
*/
|
||||||
int init_listen_sock(int port)
|
int socket_nonblocking(int sock)
|
||||||
{
|
{
|
||||||
struct sockaddr_in laddr;
|
int flags;
|
||||||
int i = 1;
|
|
||||||
|
|
||||||
assert(port > 0);
|
flags = fcntl(sock, F_GETFL, 0);
|
||||||
|
return fcntl(sock, F_SETFL, flags | O_NONBLOCK);
|
||||||
if ((setup_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
|
||||||
log("ERROR init_listen_sock: socket (%s)", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setsockopt(setup_fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0) {
|
/*
|
||||||
log("ERROR init_listen_sock: setsockopt (%s)",
|
* Set the socket to blocking -rjkaes
|
||||||
strerror(errno));
|
*/
|
||||||
return -1;
|
int socket_blocking(int sock)
|
||||||
|
{
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
flags = fcntl(sock, F_GETFL, 0);
|
||||||
|
return fcntl(sock, F_SETFL, flags & ~O_NONBLOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&listen_sock_addr, 0, sizeof(listen_sock_addr));
|
/*
|
||||||
memset(&laddr, 0, sizeof(laddr));
|
* Start listening to a socket. Create a socket with the selected port.
|
||||||
laddr.sin_family = AF_INET;
|
* The size of the socket address will be returned to the caller through
|
||||||
laddr.sin_port = htons(port);
|
* the pointer, while the socket is returned as a default return.
|
||||||
|
* - rjkaes
|
||||||
|
*/
|
||||||
|
int listen_sock(unsigned int port, socklen_t *addrlen)
|
||||||
|
{
|
||||||
|
int listenfd;
|
||||||
|
const int on = 1;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
|
listenfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||||
|
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(port);
|
||||||
|
|
||||||
if (config.ipAddr) {
|
if (config.ipAddr) {
|
||||||
laddr.sin_addr.s_addr = inet_addr(config.ipAddr);
|
addr.sin_addr.s_addr = inet_addr(config.ipAddr);
|
||||||
} else {
|
} else {
|
||||||
laddr.sin_addr.s_addr = inet_addr("0.0.0.0");
|
addr.sin_addr.s_addr = inet_addr("0.0.0.0");
|
||||||
}
|
|
||||||
if (bind(setup_fd, (struct sockaddr *) &laddr, sizeof(laddr)) < 0) {
|
|
||||||
log("ERROR init_listen_sock: bind (%s)", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if ((listen(setup_fd, MAXLISTEN)) != 0) {
|
|
||||||
log("ERROR init_listen_sock: listen (%s)", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
bind(listenfd, (struct sockaddr *) &addr, sizeof(addr));
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
listen(listenfd, MAXLISTEN);
|
||||||
* Grab a pending connection
|
|
||||||
*/
|
|
||||||
int listen_sock(void)
|
|
||||||
{
|
|
||||||
static int sock;
|
|
||||||
int sz = sizeof(listen_sock_addr);
|
|
||||||
|
|
||||||
if ((sock = accept(setup_fd, &listen_sock_addr, &sz)) < 0) {
|
*addrlen = sizeof(addr);
|
||||||
if (errno != ECONNABORTED
|
|
||||||
#ifdef EPROTO
|
|
||||||
&& errno != EPROTO
|
|
||||||
#endif
|
|
||||||
#ifdef EWOULDBLOCK
|
|
||||||
&& errno != EWOULDBLOCK
|
|
||||||
#endif
|
|
||||||
&& errno != EINTR)
|
|
||||||
log("ERROR listen_sock: accept (%s)", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
stats.num_listens++;
|
|
||||||
|
|
||||||
return sock;
|
return listenfd;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Stop listening on a socket.
|
|
||||||
*/
|
|
||||||
void de_init_listen_sock(void)
|
|
||||||
{
|
|
||||||
close(setup_fd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -224,17 +156,12 @@ char *getpeer_ip(int fd, char *ipaddr)
|
|||||||
struct sockaddr_in name;
|
struct sockaddr_in name;
|
||||||
int namelen = sizeof(name);
|
int namelen = sizeof(name);
|
||||||
|
|
||||||
assert(fd >= 0);
|
|
||||||
assert(ipaddr);
|
|
||||||
|
|
||||||
memset(ipaddr, '\0', PEER_IP_LENGTH);
|
|
||||||
|
|
||||||
if (getpeername(fd, (struct sockaddr *) &name, &namelen) != 0) {
|
if (getpeername(fd, (struct sockaddr *) &name, &namelen) != 0) {
|
||||||
log("ERROR Connect: 'could not get peer name'");
|
log(LOG_ERR, "Connect: 'could not get peer name'");
|
||||||
} else {
|
} else {
|
||||||
strncpy(ipaddr,
|
strlcpy(ipaddr,
|
||||||
inet_ntoa(*(struct in_addr *) &name.sin_addr.s_addr),
|
inet_ntoa(*(struct in_addr *) &name.sin_addr.s_addr),
|
||||||
PEER_IP_LENGTH - 1);
|
PEER_IP_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ipaddr;
|
return ipaddr;
|
||||||
@ -250,153 +177,46 @@ char *getpeer_string(int fd, char *string)
|
|||||||
int namelen = sizeof(name);
|
int namelen = sizeof(name);
|
||||||
struct hostent *peername;
|
struct hostent *peername;
|
||||||
|
|
||||||
assert(fd >= 0);
|
|
||||||
assert(string);
|
|
||||||
|
|
||||||
memset(string, '\0', PEER_STRING_LENGTH);
|
|
||||||
|
|
||||||
if (getpeername(fd, (struct sockaddr *) &name, &namelen) != 0) {
|
if (getpeername(fd, (struct sockaddr *) &name, &namelen) != 0) {
|
||||||
log("ERROR Connect: 'could not get peer name'");
|
log(LOG_ERR, "Connect: 'could not get peer name'");
|
||||||
} else {
|
} else {
|
||||||
if (
|
SOCK_LOCK();
|
||||||
(peername =
|
peername = gethostbyaddr((char *)&name.sin_addr.s_addr,
|
||||||
gethostbyaddr((char *) &name.sin_addr.s_addr,
|
|
||||||
sizeof(name.sin_addr.s_addr),
|
sizeof(name.sin_addr.s_addr),
|
||||||
AF_INET)) != NULL) {
|
AF_INET);
|
||||||
strncpy(string, peername->h_name,
|
if (peername) {
|
||||||
PEER_STRING_LENGTH - 1);
|
strlcpy(string, peername->h_name, PEER_STRING_LENGTH);
|
||||||
}
|
}
|
||||||
|
SOCK_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t readline(int fd, void *vptr, size_t maxlen)
|
||||||
/*
|
|
||||||
* Okay, this is a wacked out function. The basic gist is that we read in one
|
|
||||||
* line from the socket and return it in "line". However, if we can't pull in
|
|
||||||
* one complete line (up to an including the '\n') then we need to store it in
|
|
||||||
* the buffer's "working_string". Fun. :)
|
|
||||||
* -- rjkaes
|
|
||||||
*/
|
|
||||||
int readline(int fd, struct buffer_s *buffer, char **line)
|
|
||||||
{
|
{
|
||||||
char inbuf[BUFFER];
|
ssize_t n, rc;
|
||||||
int bytesin;
|
char c, *ptr;
|
||||||
char *endline = NULL;
|
|
||||||
char *newline;
|
|
||||||
unsigned long length;
|
|
||||||
|
|
||||||
assert(fd >= 0);
|
|
||||||
assert(buffer);
|
|
||||||
assert(line);
|
|
||||||
|
|
||||||
*line = NULL;
|
|
||||||
|
|
||||||
/* Inspect the queue. */
|
|
||||||
if ((bytesin = recv(fd, inbuf, BUFFER - 1, MSG_PEEK)) <= 0) {
|
|
||||||
goto CONN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer->working_length == 0) {
|
|
||||||
/* There is no working line, so read in a line of text. */
|
|
||||||
|
|
||||||
/* Okay, check to see if there is a '\n' in this. */
|
|
||||||
endline = xstrstr(inbuf, "\n", bytesin, FALSE);
|
|
||||||
|
|
||||||
if (endline) {
|
|
||||||
/* Yes, we have a complete line. */
|
|
||||||
*(++endline) = '\0';
|
|
||||||
length = strlen(inbuf);
|
|
||||||
|
|
||||||
/* Actually pull the data off the queue */
|
|
||||||
if ((bytesin = recv(fd, inbuf, length, 0) <= 0)) {
|
|
||||||
goto CONN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
*line = xstrdup(inbuf);
|
|
||||||
return strlen(*line);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Well, we don't have a complete line, so add it to the
|
|
||||||
* working_string.
|
|
||||||
*/
|
|
||||||
if (!(buffer->working_string = xmalloc(bytesin))) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((bytesin = recv(fd, inbuf, bytesin, 0)) <= 0) {
|
|
||||||
safefree(buffer->working_string);
|
|
||||||
goto CONN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(buffer->working_string, inbuf, bytesin);
|
|
||||||
buffer->working_length = bytesin;
|
|
||||||
|
|
||||||
|
ptr = vptr;
|
||||||
|
for (n = 1; n < maxlen; n++) {
|
||||||
|
again:
|
||||||
|
if ((rc = read(fd, &c, 1)) == 1) {
|
||||||
|
*ptr++ = c;
|
||||||
|
if (c == '\n')
|
||||||
|
break;
|
||||||
|
} else if (rc == 0) {
|
||||||
|
if (n == 1)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
else
|
||||||
|
break;
|
||||||
/*
|
} else {
|
||||||
* Alright, we do have a working line, so read in more data and see
|
if (errno == EINTR)
|
||||||
* if there is a '\n' in it.
|
goto again;
|
||||||
*/
|
|
||||||
endline = xstrstr(inbuf, "\n", bytesin, FALSE);
|
|
||||||
|
|
||||||
if (endline) {
|
|
||||||
/*
|
|
||||||
* Great, there was a "\n" found, so combine with
|
|
||||||
* working_string.
|
|
||||||
*/
|
|
||||||
*(++endline) = '\0';
|
|
||||||
length = strlen(inbuf);
|
|
||||||
|
|
||||||
if (!(*line = xmalloc(bytesin + buffer->working_length + 1))) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pull the data off */
|
|
||||||
if ((bytesin = recv(fd, inbuf, bytesin, 0)) <= 0) {
|
|
||||||
goto CONN_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy all the data into a new line */
|
*ptr = 0;
|
||||||
memcpy(*line, buffer->working_string, buffer->working_length);
|
return n;
|
||||||
memcpy(*line + buffer->working_length, inbuf, bytesin);
|
|
||||||
|
|
||||||
*(*line + buffer->working_length + bytesin + 1) = '\0';
|
|
||||||
|
|
||||||
safefree(buffer->working_string);
|
|
||||||
buffer->working_length = 0;
|
|
||||||
|
|
||||||
return strlen(*line);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Well, we have a working line and still don't have a complete line.
|
|
||||||
* Add the new data to the working line and return.
|
|
||||||
*/
|
|
||||||
if (!(newline = xmalloc(buffer->working_length + bytesin))) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((bytesin = recv(fd, inbuf, bytesin, 0)) <= 0) {
|
|
||||||
goto CONN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(newline, buffer->working_string, buffer->working_length);
|
|
||||||
memcpy(newline + buffer->working_length, inbuf, bytesin);
|
|
||||||
|
|
||||||
safefree(buffer->working_string);
|
|
||||||
buffer->working_string = newline;
|
|
||||||
buffer->working_length += bytesin;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Handle all the errors a socket could produce. */
|
|
||||||
CONN_ERROR:
|
|
||||||
if (bytesin == 0 || (errno != EAGAIN && errno != EINTR)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
22
src/sock.h
22
src/sock.h
@ -1,4 +1,4 @@
|
|||||||
/* $Id: sock.h,v 1.1.1.1 2000-02-16 17:32:23 sdyoung Exp $
|
/* $Id: sock.h,v 1.2 2000-09-11 23:56:32 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* See 'sock.c' for a detailed description.
|
* See 'sock.c' for a detailed description.
|
||||||
*
|
*
|
||||||
@ -16,25 +16,23 @@
|
|||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SOCK_H_
|
#ifndef _TINYPROXY_SOCK_H_
|
||||||
#define _SOCK_H_ 1
|
#define _TINYPROXY_SOCK_H_
|
||||||
|
|
||||||
#include "buffer.h"
|
|
||||||
|
|
||||||
#define PEER_IP_LENGTH 16
|
#define PEER_IP_LENGTH 16
|
||||||
#define PEER_STRING_LENGTH 256
|
#define PEER_STRING_LENGTH 256
|
||||||
|
|
||||||
extern int setup_fd;
|
#define MAXLINE (1024 * 4)
|
||||||
|
|
||||||
extern int opensock(char *ip_addr, int port);
|
extern int opensock(char *ip_addr, int port);
|
||||||
extern int opensock_inaddr(struct in_addr *inaddr, int port);
|
extern int listen_sock(unsigned int port, socklen_t *addrlen);
|
||||||
extern int init_listen_sock(int port);
|
|
||||||
extern int listen_sock(void);
|
extern int socket_nonblocking(int sock);
|
||||||
extern void de_init_listen_sock(void);
|
extern int socket_blocking(int sock);
|
||||||
extern int setsocketopt(int *sock_fd, int options, int flip);
|
|
||||||
|
|
||||||
extern char *getpeer_ip(int fd, char *ipaddr);
|
extern char *getpeer_ip(int fd, char *ipaddr);
|
||||||
extern char *getpeer_string(int fd, char *string);
|
extern char *getpeer_string(int fd, char *string);
|
||||||
extern int readline(int fd, struct buffer_s *buffer, char **line);
|
|
||||||
|
extern ssize_t readline(int fd, void *vptr, size_t maxlen);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user