Add some TRACE messages
[MonkeyD.git] / src / socket.c
blob327cd311c662876512c6611bf31c421d34e99043
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /* Monkey HTTP Daemon
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.
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <time.h>
26 #include <arpa/inet.h>
27 #include <netinet/tcp.h>
28 #include <sys/socket.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <string.h>
33 #include "socket.h"
34 #include "memory.h"
35 #include "utils.h"
37 /*
38 * Example from:
39 * http://www.baus.net/on-tcp_cork
41 int mk_socket_set_cork_flag(int fd, int state)
44 #ifdef TRACE
45 MK_TRACE("Socket, set Cork Flag FD %i to %s", fd, (state ? "ON" : "FALSE"));
46 #endif
48 return setsockopt(fd, SOL_TCP, TCP_CORK, &state, sizeof(state));
51 int mk_socket_set_nonblocking(int sockfd)
54 #ifdef TRACE
55 MK_TRACE("Socket, set FD %i to non-blocking", sockfd);
56 #endif
58 if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0) | O_NONBLOCK) == -1) {
59 perror("fcntl");
60 return -1;
62 return 0;
65 int mk_socket_set_tcp_nodelay(int sockfd)
67 int on = 1;
68 return setsockopt(sockfd, SOL_TCP, TCP_NODELAY, &on, sizeof(on));
71 int mk_socket_get_ip(int socket, char *ipv4)
73 int ipv4_len = 16;
74 socklen_t len;
75 struct sockaddr_in m_addr;
77 len = sizeof(m_addr);
78 getpeername(socket, (struct sockaddr *) &m_addr, &len);
79 inet_ntop(PF_INET, &m_addr.sin_addr, ipv4, ipv4_len);
81 return 0;
84 int mk_socket_close(int socket)
86 return close(socket);
89 int mk_socket_create()
91 int sockfd;
93 if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
94 perror("client: socket");
95 return -1;
98 return sockfd;
101 int mk_socket_connect(int sockfd, char *server, int port)
103 int res;
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)));
112 if (res < 0) {
113 perror("Can't set remote->sin_addr.s_addr");
114 mk_mem_free(remote);
115 return -1;
117 else if (res == 0) {
118 perror("Invalid IP address\n");
119 mk_mem_free(remote);
120 return -1;
123 remote->sin_port = htons(port);
124 if (connect(sockfd,
125 (struct sockaddr *) remote, sizeof(struct sockaddr)) == -1) {
126 close(sockfd);
127 perror("connect");
128 return -1;
130 mk_mem_free(remote);
131 return 0;
134 void mk_socket_reset(int socket)
136 int status = 1;
138 if (setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &status, sizeof(int)) ==
139 -1) {
140 perror("setsockopt");
141 exit(1);
145 /* Just IPv4 for now... */
146 int mk_socket_server(int port, char *listen_addr)
148 int fd;
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 */
161 mk_socket_reset(fd);
163 if (bind(fd, (struct sockaddr *) &local_sockaddr_in,
164 sizeof(struct sockaddr)) != 0) {
165 perror("bind");
166 printf("Error: Port %i cannot be used\n", port);
167 exit(1);
170 /* Listen queue:
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) {
175 perror("listen");
176 exit(1);
179 return fd;