1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
5 * Copyright (C) 2008-2009 Eduardo Silva P.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Library General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 #include <arpa/inet.h>
27 #include <netinet/tcp.h>
28 #include <sys/socket.h>
39 * http://www.baus.net/on-tcp_cork
41 int mk_socket_set_cork_flag(int fd
, int state
)
45 MK_TRACE("Socket, set Cork Flag FD %i to %s", fd
, (state
? "ON" : "FALSE"));
48 return setsockopt(fd
, SOL_TCP
, TCP_CORK
, &state
, sizeof(state
));
51 int mk_socket_set_nonblocking(int sockfd
)
55 MK_TRACE("Socket, set FD %i to non-blocking", sockfd
);
58 if (fcntl(sockfd
, F_SETFL
, fcntl(sockfd
, F_GETFD
, 0) | O_NONBLOCK
) == -1) {
65 int mk_socket_set_tcp_nodelay(int sockfd
)
68 return setsockopt(sockfd
, SOL_TCP
, TCP_NODELAY
, &on
, sizeof(on
));
71 int mk_socket_get_ip(int socket
, char *ipv4
)
75 struct sockaddr_in m_addr
;
78 getpeername(socket
, (struct sockaddr
*) &m_addr
, &len
);
79 inet_ntop(PF_INET
, &m_addr
.sin_addr
, ipv4
, ipv4_len
);
84 int mk_socket_close(int socket
)
89 int mk_socket_create()
93 if ((sockfd
= socket(PF_INET
, SOCK_STREAM
, 0)) == -1) {
94 perror("client: socket");
101 int mk_socket_connect(int sockfd
, char *server
, int port
)
104 struct sockaddr_in
*remote
;
106 remote
= (struct sockaddr_in
*)
107 mk_mem_malloc_z(sizeof(struct sockaddr_in
));
108 remote
->sin_family
= AF_INET
;
110 res
= inet_pton(AF_INET
, server
, (void *) (&(remote
->sin_addr
.s_addr
)));
113 perror("Can't set remote->sin_addr.s_addr");
118 perror("Invalid IP address\n");
123 remote
->sin_port
= htons(port
);
125 (struct sockaddr
*) remote
, sizeof(struct sockaddr
)) == -1) {
134 void mk_socket_reset(int socket
)
138 if (setsockopt(socket
, SOL_SOCKET
, SO_REUSEADDR
, &status
, sizeof(int)) ==
140 perror("setsockopt");
145 /* Just IPv4 for now... */
146 int mk_socket_server(int port
, char *listen_addr
)
149 struct sockaddr_in local_sockaddr_in
;
151 /* Create server socket */
152 fd
= socket(PF_INET
, SOCK_STREAM
, 0);
153 mk_socket_set_tcp_nodelay(fd
);
155 local_sockaddr_in
.sin_family
= AF_INET
;
156 local_sockaddr_in
.sin_port
= htons(port
);
157 inet_pton(AF_INET
, listen_addr
, &local_sockaddr_in
.sin_addr
.s_addr
);
158 memset(&(local_sockaddr_in
.sin_zero
), '\0', 8);
160 /* Avoid bind issues, reset socket */
163 if (bind(fd
, (struct sockaddr
*) &local_sockaddr_in
,
164 sizeof(struct sockaddr
)) != 0) {
166 printf("Error: Port %i cannot be used\n", port
);
171 * The queue limit is given by /proc/sys/net/core/somaxconn
172 * we need to add a dynamic function to get that value on fly
174 if ((listen(fd
, 1024)) != 0) {