1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 #include <arpa/inet.h>
27 #include <netinet/tcp.h>
28 #include <sys/socket.h>
38 * http://www.baus.net/on-tcp_cork
40 int mk_socket_set_cork_flag(int fd
, int state
)
42 return setsockopt(fd
, SOL_TCP
, TCP_CORK
, &state
, sizeof(state
));
45 int mk_socket_set_nonblocking(int sockfd
)
47 if (fcntl(sockfd
, F_SETFL
, fcntl(sockfd
, F_GETFD
, 0)|O_NONBLOCK
) == -1) {
54 int mk_socket_set_tcp_nodelay(int sockfd
)
57 return setsockopt(sockfd
, SOL_TCP
, TCP_NODELAY
, &on
, sizeof(on
));
60 char *mk_socket_get_ip(int socket
)
65 struct sockaddr_in m_addr
;
67 ipv4
= mk_mem_malloc(ipv4_len
);
75 getpeername(socket
, (struct sockaddr
*)&m_addr
, &len
);
76 return (char *) inet_ntop(PF_INET
, &m_addr
.sin_addr
, ipv4
, ipv4_len
);
79 int mk_socket_close(int socket
)
84 int mk_socket_timeout(int s
, char *buf
, int len
,
85 int timeout
, int recv_send
)
88 time_t init_time
, max_time
;
93 max_time
= init_time
+ timeout
;
101 if(recv_send
==ST_RECV
)
102 n
=select(s
+1,&fds
,NULL
,NULL
,&tv
); // recv
104 n
=select(s
+1,NULL
,&fds
,NULL
,&tv
); // send
112 //pthread_kill(pthread_self(), SIGPIPE);
116 if(recv_send
==ST_RECV
){
117 status
=recv(s
,buf
,len
, 0);
120 status
=send(s
,buf
,len
, 0);
124 if(time(NULL
) >= max_time
){
125 //pthread_kill(pthread_self(), SIGPIPE);
132 int mk_socket_create()
136 if ((sockfd
= socket(PF_INET
, SOCK_STREAM
, 0)) == -1) {
137 perror("client: socket");
144 int mk_socket_connect(int sockfd
, char *server
, int port
)
147 struct sockaddr_in
*remote
;
149 remote
= (struct sockaddr_in
*)
150 mk_mem_malloc_z(sizeof(struct sockaddr_in
));
151 remote
->sin_family
= AF_INET
;
152 res
= inet_pton(AF_INET
, server
, (void *)(&(remote
->sin_addr
.s_addr
)));
156 perror("Can't set remote->sin_addr.s_addr");
161 perror("Invalid IP address\n");
166 remote
->sin_port
= htons(port
);
168 (struct sockaddr
*)remote
,
169 sizeof(struct sockaddr
)) == -1)
172 perror("client: connect");
179 void mk_socket_reset(int socket
)
183 if(setsockopt(socket
,SOL_SOCKET
,SO_REUSEADDR
,&status
,sizeof(int))==-1) {
184 perror("setsockopt");
189 /* Just IPv4 for now... */
190 int mk_socket_server(int port
)
193 struct sockaddr_in local_sockaddr_in
;
195 /* Create server socket */
196 fd
=socket(PF_INET
,SOCK_STREAM
,0);
197 mk_socket_set_tcp_nodelay(fd
);
198 //mk_socket_set_nonblocking(fd);
200 local_sockaddr_in
.sin_family
=AF_INET
;
201 local_sockaddr_in
.sin_port
=htons(port
);
202 local_sockaddr_in
.sin_addr
.s_addr
=INADDR_ANY
;
203 memset(&(local_sockaddr_in
.sin_zero
),'\0',8);
205 /* Avoid bind issues, reset socket */
208 if(bind(fd
,(struct sockaddr
*)&local_sockaddr_in
,
209 sizeof(struct sockaddr
)) != 0)
212 printf("Error: Port %i cannot be used\n", port
);
217 * The queue limit is given by /proc/sys/net/core/somaxconn
218 * we need to add a dynamic function to get that value on fly
220 if((listen(fd
, 1024))!=0) {