Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,178 +0,0 @@
1
-/*
2
- * Copyright (C) 2001-2003 FhG Fokus
3
- *
4
- * This file is part of Kamailio, a free SIP server.
5
- *
6
- * Kamailio is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version
10
- *
11
- * Kamailio is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program; if not, write to the Free Software
18
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19
- */
20
-
21
-/*!
22
- * \file
23
- * \brief Kamailio core :: send with timeout for stream and datagram sockets
24
- * \ingroup core
25
- * Module: \ref core
26
- */
27
-
28
-#include <string.h>
29
-#include <errno.h>
30
-#include <sys/poll.h>
31
-
32
-#include <sys/types.h>
33
-#include <sys/socket.h>
34
-#include <sys/uio.h>
35
-
36
-#include "dprint.h"
37
-#include "timer.h"
38
-#include "timer_ticks.h"
39
-
40
-/* the functions below are very similar => some generic macros */
41
-#define TSEND_INIT \
42
-	int n; \
43
-	struct pollfd pf; \
44
-	ticks_t expire; \
45
-	s_ticks_t diff; \
46
-	expire=get_ticks_raw()+MS_TO_TICKS((ticks_t)timeout); \
47
-	pf.fd=fd; \
48
-	pf.events=POLLOUT
49
-
50
-#define TSEND_POLL(f_name) \
51
-poll_loop: \
52
-	while(1){ \
53
-		if (timeout==-1) \
54
-			n=poll(&pf, 1, -1); \
55
-		else{ \
56
-			diff=expire-get_ticks_raw(); \
57
-			if (diff<=0){ \
58
-				LOG(L_ERR, "ERROR: " f_name ": send timeout (%d)\n", timeout);\
59
-				goto error; \
60
-			} \
61
-			n=poll(&pf, 1, TICKS_TO_MS((ticks_t)diff)); \
62
-		} \
63
-		if (n<0){ \
64
-			if (errno==EINTR) continue; /* signal, ignore */ \
65
-			LOG(L_ERR, "ERROR: " f_name ": poll failed: %s [%d]\n", \
66
-					strerror(errno), errno); \
67
-			goto error; \
68
-		}else if (n==0){ \
69
-			/* timeout */ \
70
-			LOG(L_ERR, "ERROR: " f_name ": send timeout (p %d)\n", timeout); \
71
-			goto error; \
72
-		} \
73
-		if (pf.revents&POLLOUT){ \
74
-			/* we can write again */ \
75
-			goto again; \
76
-		}else if (pf.revents&(POLLERR|POLLHUP|POLLNVAL)){ \
77
-			LOG(L_ERR, "ERROR: " f_name ": bad poll flags %x\n", \
78
-					pf.revents); \
79
-			goto error; \
80
-		} \
81
-		/* if POLLIN or POLLPRI or other non-harmful events happened,    \
82
-		 * continue ( although poll should never signal them since we're  \
83
-		 * not interested in them => we should never reach this point) */ \
84
-	} 
85
-
86
-
87
-#define TSEND_ERR_CHECK(f_name)\
88
-	if (n<0){ \
89
-		if (errno==EINTR) goto again; \
90
-		else if (errno!=EAGAIN && errno!=EWOULDBLOCK){ \
91
-			LOG(L_ERR, "ERROR: " f_name ": failed to send: (%d) %s\n", \
92
-					errno, strerror(errno)); \
93
-			goto error; \
94
-		}else goto poll_loop; \
95
-	}
96
-	
97
-
98
-
99
-/* sends on fd (which must be O_NONBLOCK if you want a finite timeout); if it
100
- * cannot send any data
101
- * in timeout milliseconds it will return ERROR
102
- * if timeout==-1, it waits forever
103
- * returns: -1 on error, or number of bytes written
104
- *  (if less than len => couldn't send all)
105
- *  bugs: signals will reset the timer
106
- */
107
-int tsend_stream(int fd, const char* buf, unsigned int len, int timeout)
108
-{
109
-	int written;
110
-	TSEND_INIT;
111
-	
112
-	written=0;
113
-again:
114
-	n=send(fd, buf, len,
115
-#ifdef HAVE_MSG_NOSIGNAL
116
-			MSG_NOSIGNAL
117
-#else
118
-			0
119
-#endif
120
-		);
121
-	TSEND_ERR_CHECK("tsend_stream");
122
-	written+=n; 
123
-	if (n<(int)len){ 
124
-		/* partial write */ 
125
-		buf+=n; 
126
-		len-=n; 
127
-	}else{ 
128
-		/* successful full write */ 
129
-		return written;
130
-	}
131
-	TSEND_POLL("tsend_stream");
132
-error:
133
-	return -1;
134
-}
135
-
136
-
137
-
138
-/* sends on dgram fd (which must be O_NONBLOCK); if it cannot send any data
139
- * in timeout milliseconds it will return ERROR
140
- * returns: -1 on error, or number of bytes written
141
- *  (if less than len => couldn't send all)
142
- *  bugs: signals will reset the timer
143
- */
144
-int tsend_dgram(int fd, const char* buf, unsigned int len, 
145
-				const struct sockaddr* to, socklen_t tolen, int timeout)
146
-{
147
-	TSEND_INIT;
148
-again:
149
-	n=sendto(fd, buf, len, 0, to, tolen);
150
-	TSEND_ERR_CHECK("tsend_dgram");
151
-	/* we don't care about partial writes: they shouldn't happen on 
152
-	 * a datagram socket */
153
-	return n;
154
-	TSEND_POLL("tsend_datagram");
155
-error:
156
-	return -1;
157
-}
158
-
159
-	
160
-/* sends on connected datagram fd (which must be O_NONBLOCK); 
161
- * if it cannot send any data in timeout milliseconds it will return ERROR
162
- * returns: -1 on error, or number of bytes written
163
- *  (if less than len => couldn't send all)
164
- *  bugs: signals will reset the timer
165
- */
166
-
167
-int tsend_dgram_ev(int fd, const struct iovec* v, int count, int timeout)
168
-{
169
-	TSEND_INIT;
170
-again:
171
-	n=writev(fd, v, count);
172
-	TSEND_ERR_CHECK("tsend_datagram_ev");
173
-	return n;
174
-	TSEND_POLL("tsend_datagram_ev");
175
-error:
176
-	return -1;
177
-}
178
-
Browse code

core Update headers, change "SIP-router" to "Kamailio", update doxygen file headers

Olle E. Johansson authored on 03/01/2015 14:15:58
Showing 1 changed files
... ...
@@ -8,11 +8,6 @@
8 8
  * the Free Software Foundation; either version 2 of the License, or
9 9
  * (at your option) any later version
10 10
  *
11
- * For a license to use the ser software under conditions
12
- * other than those described here, or to purchase support for this
13
- * software, please contact iptel.org by e-mail at the following addresses:
14
- *    info@iptel.org
15
- *
16 11
  * Kamailio is distributed in the hope that it will be useful,
17 12
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 13
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Browse code

Core Removed history, svn $id$ and doxygen udpates on the .c files

Olle E. Johansson authored on 03/01/2015 09:53:17
Showing 1 changed files
... ...
@@ -1,11 +1,9 @@
1 1
 /*
2
- * $Id$
3
- *
4 2
  * Copyright (C) 2001-2003 FhG Fokus
5 3
  *
6
- * This file is part of ser, a free SIP server.
4
+ * This file is part of Kamailio, a free SIP server.
7 5
  *
8
- * ser is free software; you can redistribute it and/or modify
6
+ * Kamailio is free software; you can redistribute it and/or modify
9 7
  * it under the terms of the GNU General Public License as published by
10 8
  * the Free Software Foundation; either version 2 of the License, or
11 9
  * (at your option) any later version
... ...
@@ -15,7 +13,7 @@
15 13
  * software, please contact iptel.org by e-mail at the following addresses:
16 14
  *    info@iptel.org
17 15
  *
18
- * ser is distributed in the hope that it will be useful,
16
+ * Kamailio is distributed in the hope that it will be useful,
19 17
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 18
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 19
  * GNU General Public License for more details.
... ...
@@ -24,19 +22,10 @@
24 22
  * along with this program; if not, write to the Free Software
25 23
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
26 24
  */
27
-/*
28
- * send with timeout for stream and datagram sockets
29
- * 
30
- * History:
31
- * --------
32
- *  2004-02-26  created by andrei
33
- *  2003-03-03  switched to heavy macro use, added tsend_dgram_ev (andrei) 
34
- *  2006-02-03  tsend* will wait forever if timeout==-1 (andrei)
35
- */
36 25
 
37 26
 /*!
38 27
  * \file
39
- * \brief SIP-router core :: 
28
+ * \brief Kamailio core :: send with timeout for stream and datagram sockets
40 29
  * \ingroup core
41 30
  * Module: \ref core
42 31
  */
Browse code

all: updated FSF address in GPL text

Anthony Messina authored on 04/07/2014 09:36:37 • Daniel-Constantin Mierla committed on 04/07/2014 09:37:36
Showing 1 changed files
... ...
@@ -22,7 +22,7 @@
22 22
  *
23 23
  * You should have received a copy of the GNU General Public License
24 24
  * along with this program; if not, write to the Free Software
25
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
26 26
  */
27 27
 /*
28 28
  * send with timeout for stream and datagram sockets
Browse code

tsend: s/char*/const char*/ in function params.

Andrei Pelinescu-Onciul authored on 23/06/2010 21:13:23
Showing 1 changed files
... ...
@@ -120,7 +120,7 @@ poll_loop: \
120 120
  *  (if less than len => couldn't send all)
121 121
  *  bugs: signals will reset the timer
122 122
  */
123
-int tsend_stream(int fd, char* buf, unsigned int len, int timeout)
123
+int tsend_stream(int fd, const char* buf, unsigned int len, int timeout)
124 124
 {
125 125
 	int written;
126 126
 	TSEND_INIT;
... ...
@@ -157,7 +157,7 @@ error:
157 157
  *  (if less than len => couldn't send all)
158 158
  *  bugs: signals will reset the timer
159 159
  */
160
-int tsend_dgram(int fd, char* buf, unsigned int len, 
160
+int tsend_dgram(int fd, const char* buf, unsigned int len, 
161 161
 				const struct sockaddr* to, socklen_t tolen, int timeout)
162 162
 {
163 163
 	TSEND_INIT;
Browse code

Adding doxygen template to all core .c files

Please fill in after the :: to explain the function of this file.

oej authored on 10/10/2009 13:54:13
Showing 1 changed files
... ...
@@ -34,6 +34,13 @@
34 34
  *  2006-02-03  tsend* will wait forever if timeout==-1 (andrei)
35 35
  */
36 36
 
37
+/*!
38
+ * \file
39
+ * \brief SIP-router core :: 
40
+ * \ingroup core
41
+ * Module: \ref core
42
+ */
43
+
37 44
 #include <string.h>
38 45
 #include <errno.h>
39 46
 #include <sys/poll.h>
Browse code

- fix: signed/unsigned comparisons (tcp_send)

Andrei Pelinescu-Onciul authored on 22/12/2007 18:13:29
Showing 1 changed files
... ...
@@ -129,7 +129,7 @@ again:
129 129
 		);
130 130
 	TSEND_ERR_CHECK("tsend_stream");
131 131
 	written+=n; 
132
-	if (n<len){ 
132
+	if (n<(int)len){ 
133 133
 		/* partial write */ 
134 134
 		buf+=n; 
135 135
 		len-=n; 
Browse code

- tcp children number is not anymore limited (was limited to 100) - tcp connection are passed to the tcp reader processes after some data is received on them and not immediately after accept(). This speeds up accepting lots of new connections. Old behaviour can be select by undef-ing TCP_PASS_NEW_CONNECTION_ON_DATA in tcp_main.c - lots of cleanups and small fixes - tsend_stream now support waiting forever (timeout==-1)

Orientative test results:
- 50k connections to ser opened, 1 packet sent of them and then closed in 9.5s - 50-65Mb data rate on 50k connections (with 20 ser tcp processes)
- 200-240Mb data rate on 1 connection

Andrei Pelinescu-Onciul authored on 03/02/2006 21:56:23
Showing 1 changed files
... ...
@@ -31,6 +31,7 @@
31 31
  * --------
32 32
  *  2004-02-26  created by andrei
33 33
  *  2003-03-03  switched to heavy macro use, added tsend_dgram_ev (andrei) 
34
+ *  2006-02-03  tsend* will wait forever if timeout==-1 (andrei)
34 35
  */
35 36
 
36 37
 #include <string.h>
... ...
@@ -58,12 +59,16 @@
58 59
 #define TSEND_POLL(f_name) \
59 60
 poll_loop: \
60 61
 	while(1){ \
61
-		diff=expire-get_ticks_raw(); \
62
-		if (diff<=0){ \
63
-			LOG(L_ERR, "ERROR: " f_name ": send timeout (%d)\n", timeout); \
64
-			goto error; \
62
+		if (timeout==-1) \
63
+			n=poll(&pf, 1, -1); \
64
+		else{ \
65
+			diff=expire-get_ticks_raw(); \
66
+			if (diff<=0){ \
67
+				LOG(L_ERR, "ERROR: " f_name ": send timeout (%d)\n", timeout);\
68
+				goto error; \
69
+			} \
70
+			n=poll(&pf, 1, TICKS_TO_MS((ticks_t)diff)); \
65 71
 		} \
66
-		n=poll(&pf, 1, TICKS_TO_MS((ticks_t)diff)); \
67 72
 		if (n<0){ \
68 73
 			if (errno==EINTR) continue; /* signal, ignore */ \
69 74
 			LOG(L_ERR, "ERROR: " f_name ": poll failed: %s [%d]\n", \
... ...
@@ -100,8 +105,10 @@ poll_loop: \
100 105
 	
101 106
 
102 107
 
103
-/* sends on fd (which must be O_NONBLOCK); if it cannot send any data
108
+/* sends on fd (which must be O_NONBLOCK if you want a finite timeout); if it
109
+ * cannot send any data
104 110
  * in timeout milliseconds it will return ERROR
111
+ * if timeout==-1, it waits forever
105 112
  * returns: -1 on error, or number of bytes written
106 113
  *  (if less than len => couldn't send all)
107 114
  *  bugs: signals will reset the timer
Browse code

- tsend_* functions changed to obey the timeout more accurately and in all cases - unix_tx_timeout changed to milliseconds and its default value to 500 ms.

Andrei Pelinescu-Onciul authored on 10/12/2005 23:44:06
Showing 1 changed files
... ...
@@ -42,18 +42,28 @@
42 42
 #include <sys/uio.h>
43 43
 
44 44
 #include "dprint.h"
45
+#include "timer.h"
46
+#include "timer_ticks.h"
45 47
 
46 48
 /* the functions below are very similar => some generic macros */
47 49
 #define TSEND_INIT \
48 50
 	int n; \
49 51
 	struct pollfd pf; \
52
+	ticks_t expire; \
53
+	s_ticks_t diff; \
54
+	expire=get_ticks_raw()+MS_TO_TICKS((ticks_t)timeout); \
50 55
 	pf.fd=fd; \
51 56
 	pf.events=POLLOUT
52 57
 
53 58
 #define TSEND_POLL(f_name) \
54 59
 poll_loop: \
55 60
 	while(1){ \
56
-		n=poll(&pf, 1, timeout); \
61
+		diff=expire-get_ticks_raw(); \
62
+		if (diff<=0){ \
63
+			LOG(L_ERR, "ERROR: " f_name ": send timeout (%d)\n", timeout); \
64
+			goto error; \
65
+		} \
66
+		n=poll(&pf, 1, TICKS_TO_MS((ticks_t)diff)); \
57 67
 		if (n<0){ \
58 68
 			if (errno==EINTR) continue; /* signal, ignore */ \
59 69
 			LOG(L_ERR, "ERROR: " f_name ": poll failed: %s [%d]\n", \
... ...
@@ -61,7 +71,7 @@ poll_loop: \
61 71
 			goto error; \
62 72
 		}else if (n==0){ \
63 73
 			/* timeout */ \
64
-			LOG(L_ERR, "ERROR: " f_name ": send timeout (%d)\n", timeout); \
74
+			LOG(L_ERR, "ERROR: " f_name ": send timeout (p %d)\n", timeout); \
65 75
 			goto error; \
66 76
 		} \
67 77
 		if (pf.revents&POLLOUT){ \
Browse code

- Spelling checked - READMEs updated

Jan Janak authored on 24/08/2004 08:45:09
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * $Id$
3 3
  *
4
- * Copyright (C) 2001-2003 Fhg Fokus
4
+ * Copyright (C) 2001-2003 FhG Fokus
5 5
  *
6 6
  * This file is part of ser, a free SIP server.
7 7
  *
... ...
@@ -72,7 +72,7 @@ poll_loop: \
72 72
 					pf.revents); \
73 73
 			goto error; \
74 74
 		} \
75
-		/* if POLLIN or POLLPRI or other non-harmfull events happened,    \
75
+		/* if POLLIN or POLLPRI or other non-harmful events happened,    \
76 76
 		 * continue ( although poll should never signal them since we're  \
77 77
 		 * not interested in them => we should never reach this point) */ \
78 78
 	} 
... ...
@@ -91,7 +91,7 @@ poll_loop: \
91 91
 
92 92
 
93 93
 /* sends on fd (which must be O_NONBLOCK); if it cannot send any data
94
- * in timeout miliseconds it will return ERROR
94
+ * in timeout milliseconds it will return ERROR
95 95
  * returns: -1 on error, or number of bytes written
96 96
  *  (if less than len => couldn't send all)
97 97
  *  bugs: signals will reset the timer
... ...
@@ -117,7 +117,7 @@ again:
117 117
 		buf+=n; 
118 118
 		len-=n; 
119 119
 	}else{ 
120
-		/* succesfull full write */ 
120
+		/* successful full write */ 
121 121
 		return written;
122 122
 	}
123 123
 	TSEND_POLL("tsend_stream");
... ...
@@ -128,7 +128,7 @@ error:
128 128
 
129 129
 
130 130
 /* sends on dgram fd (which must be O_NONBLOCK); if it cannot send any data
131
- * in timeout miliseconds it will return ERROR
131
+ * in timeout milliseconds it will return ERROR
132 132
  * returns: -1 on error, or number of bytes written
133 133
  *  (if less than len => couldn't send all)
134 134
  *  bugs: signals will reset the timer
... ...
@@ -140,7 +140,7 @@ int tsend_dgram(int fd, char* buf, unsigned int len,
140 140
 again:
141 141
 	n=sendto(fd, buf, len, 0, to, tolen);
142 142
 	TSEND_ERR_CHECK("tsend_dgram");
143
-	/* we don't care about partial writes: they shouln't happen on 
143
+	/* we don't care about partial writes: they shouldn't happen on 
144 144
 	 * a datagram socket */
145 145
 	return n;
146 146
 	TSEND_POLL("tsend_datagram");
... ...
@@ -150,7 +150,7 @@ error:
150 150
 
151 151
 	
152 152
 /* sends on connected datagram fd (which must be O_NONBLOCK); 
153
- * if it cannot send any data in timeout miliseconds it will return ERROR
153
+ * if it cannot send any data in timeout milliseconds it will return ERROR
154 154
  * returns: -1 on error, or number of bytes written
155 155
  *  (if less than len => couldn't send all)
156 156
  *  bugs: signals will reset the timer
Browse code

- added tsend_dgram_ev (== writev+timeout) - changed parameter order for tsend_dgram

Andrei Pelinescu-Onciul authored on 03/03/2004 11:13:25
Showing 1 changed files
... ...
@@ -30,6 +30,7 @@
30 30
  * History:
31 31
  * --------
32 32
  *  2004-02-26  created by andrei
33
+ *  2003-03-03  switched to heavy macro use, added tsend_dgram_ev (andrei) 
33 34
  */
34 35
 
35 36
 #include <string.h>
... ...
@@ -38,9 +39,56 @@
38 39
 
39 40
 #include <sys/types.h>
40 41
 #include <sys/socket.h>
42
+#include <sys/uio.h>
41 43
 
42 44
 #include "dprint.h"
43 45
 
46
+/* the functions below are very similar => some generic macros */
47
+#define TSEND_INIT \
48
+	int n; \
49
+	struct pollfd pf; \
50
+	pf.fd=fd; \
51
+	pf.events=POLLOUT
52
+
53
+#define TSEND_POLL(f_name) \
54
+poll_loop: \
55
+	while(1){ \
56
+		n=poll(&pf, 1, timeout); \
57
+		if (n<0){ \
58
+			if (errno==EINTR) continue; /* signal, ignore */ \
59
+			LOG(L_ERR, "ERROR: " f_name ": poll failed: %s [%d]\n", \
60
+					strerror(errno), errno); \
61
+			goto error; \
62
+		}else if (n==0){ \
63
+			/* timeout */ \
64
+			LOG(L_ERR, "ERROR: " f_name ": send timeout (%d)\n", timeout); \
65
+			goto error; \
66
+		} \
67
+		if (pf.revents&POLLOUT){ \
68
+			/* we can write again */ \
69
+			goto again; \
70
+		}else if (pf.revents&(POLLERR|POLLHUP|POLLNVAL)){ \
71
+			LOG(L_ERR, "ERROR: " f_name ": bad poll flags %x\n", \
72
+					pf.revents); \
73
+			goto error; \
74
+		} \
75
+		/* if POLLIN or POLLPRI or other non-harmfull events happened,    \
76
+		 * continue ( although poll should never signal them since we're  \
77
+		 * not interested in them => we should never reach this point) */ \
78
+	} 
79
+
80
+
81
+#define TSEND_ERR_CHECK(f_name)\
82
+	if (n<0){ \
83
+		if (errno==EINTR) goto again; \
84
+		else if (errno!=EAGAIN && errno!=EWOULDBLOCK){ \
85
+			LOG(L_ERR, "ERROR: " f_name ": failed to send: (%d) %s\n", \
86
+					errno, strerror(errno)); \
87
+			goto error; \
88
+		}else goto poll_loop; \
89
+	}
90
+	
91
+
44 92
 
45 93
 /* sends on fd (which must be O_NONBLOCK); if it cannot send any data
46 94
  * in timeout miliseconds it will return ERROR
... ...
@@ -50,17 +98,10 @@
50 98
  */
51 99
 int tsend_stream(int fd, char* buf, unsigned int len, int timeout)
52 100
 {
53
-	int n;
54 101
 	int written;
55
-	int initial_len;
56
-	struct pollfd pf;
102
+	TSEND_INIT;
57 103
 	
58 104
 	written=0;
59
-	initial_len=len;
60
-	pf.fd=fd;
61
-	pf.events=POLLOUT;
62
-	
63
-	
64 105
 again:
65 106
 	n=send(fd, buf, len,
66 107
 #ifdef HAVE_MSG_NOSIGNAL
... ...
@@ -69,121 +110,61 @@ again:
69 110
 			0
70 111
 #endif
71 112
 		);
72
-	if (n<0){
73
-		if (errno==EINTR) goto again;
74
-		else if (errno!=EAGAIN && errno!=EWOULDBLOCK){
75
-			LOG(L_ERR, "ERROR: tsend_stream: failed to send: (%d) %s\n",
76
-						errno, strerror(errno));
77
-			goto error;
78
-		}
79
-	}
80
-	written+=n;
81
-	if (n<len){
82
-		/* partial write */
83
-		buf+=n;
84
-		len-=n;
85
-	}else{
86
-		/* succesfull full write */
87
-		goto end;
88
-	}
89
-	while(1){
90
-		n=poll(&pf, 1, timeout);
91
-		if (n<0){
92
-			if (errno==EINTR) continue; /* signal, ignore */
93
-			LOG(L_ERR, "ERROR: tsend_stream: poll failed: %s [%d]\n",
94
-					strerror(errno), errno);
95
-			goto error;
96
-		}else if (n==0){
97
-			/* timeout */
98
-			LOG(L_ERR, "ERROR: tsend_stream: send timeout (%d)\n", timeout);
99
-			goto error;
100
-		}
101
-		if (pf.revents&POLLOUT){
102
-			/* we can write again */
103
-			goto again;
104
-		}else if (pf.revents&(POLLERR|POLLHUP|POLLNVAL)){
105
-			LOG(L_ERR, "ERROR: tsend_stream: bad poll flags %x\n", 
106
-					pf.revents);
107
-			goto error;
108
-		}
109
-		/* if POLLIN or POLLPRI or other non-harmfull events happened,
110
-		 * continue ( although poll should never signal them since we're
111
-		 * not interested in them => we should never reach this point) */
113
+	TSEND_ERR_CHECK("tsend_stream");
114
+	written+=n; 
115
+	if (n<len){ 
116
+		/* partial write */ 
117
+		buf+=n; 
118
+		len-=n; 
119
+	}else{ 
120
+		/* succesfull full write */ 
121
+		return written;
112 122
 	}
123
+	TSEND_POLL("tsend_stream");
113 124
 error:
114 125
 	return -1;
115
-end:
116
-	return written;
117 126
 }
118 127
 
119 128
 
120 129
 
121
-/* sends on dram fd (which must be O_NONBLOCK); if it cannot send any data
130
+/* sends on dgram fd (which must be O_NONBLOCK); if it cannot send any data
122 131
  * in timeout miliseconds it will return ERROR
123 132
  * returns: -1 on error, or number of bytes written
124 133
  *  (if less than len => couldn't send all)
125 134
  *  bugs: signals will reset the timer
126 135
  */
127
-int tsend_dgram(int fd, char* buf, unsigned int len, int timeout,
128
-				const struct sockaddr* to, socklen_t tolen)
136
+int tsend_dgram(int fd, char* buf, unsigned int len, 
137
+				const struct sockaddr* to, socklen_t tolen, int timeout)
129 138
 {
130
-	int n;
131
-	int written;
132
-	int initial_len;
133
-	struct pollfd pf;
134
-	
135
-	written=0;
136
-	initial_len=len;
137
-	pf.fd=fd;
138
-	pf.events=POLLOUT;
139
-	
139
+	TSEND_INIT;
140 140
 again:
141 141
 	n=sendto(fd, buf, len, 0, to, tolen);
142
-	if (n<0){
143
-		if (errno==EINTR) goto again;
144
-		else if (errno!=EAGAIN && errno!=EWOULDBLOCK){
145
-			LOG(L_ERR, "ERROR: tsend_dgram: failed to send: (%d) %s\n",
146
-						errno, strerror(errno));
147
-			goto error;
148
-		}
149
-	}
150
-	written+=n;
151
-	if (n<len){
152
-		/* partial write */
153
-		LOG(L_CRIT, "BUG: tsend_dgram: partial write on datagram socket\n");
154
-		goto error;
155
-	}else{
156
-		/* succesfull full write */
157
-		goto end;
158
-	}
159
-	while(1){
160
-		n=poll(&pf, 1, timeout);
161
-		if (n<0){
162
-			if (errno==EINTR) continue; /* signal, ignore */
163
-			LOG(L_ERR, "ERROR: tsend_dgram: poll failed: %s [%d]\n",
164
-					strerror(errno), errno);
165
-			goto error;
166
-		}else if (n==0){
167
-			/* timeout */
168
-			LOG(L_ERR, "ERROR: tsend_dgram: send timeout (%d)\n", timeout);
169
-			goto error;
170
-		}
171
-		if (pf.revents&POLLOUT){
172
-			/* we can write again */
173
-			goto again;
174
-		}else if (pf.revents&(POLLERR|POLLHUP|POLLNVAL)){
175
-			LOG(L_ERR, "ERROR: tsend_dgram: bad poll flags %x\n", 
176
-					pf.revents);
177
-			goto error;
178
-		}
179
-		/* if POLLIN or POLLPRI or other non-harmfull events happened,
180
-		 * continue ( although poll should never signal them since we're
181
-		 * not interested in them => we should never reach this point) */
182
-	}
142
+	TSEND_ERR_CHECK("tsend_dgram");
143
+	/* we don't care about partial writes: they shouln't happen on 
144
+	 * a datagram socket */
145
+	return n;
146
+	TSEND_POLL("tsend_datagram");
183 147
 error:
184 148
 	return -1;
185
-end:
186
-	return written;
187 149
 }
188 150
 
189 151
 	
152
+/* sends on connected datagram fd (which must be O_NONBLOCK); 
153
+ * if it cannot send any data in timeout miliseconds it will return ERROR
154
+ * returns: -1 on error, or number of bytes written
155
+ *  (if less than len => couldn't send all)
156
+ *  bugs: signals will reset the timer
157
+ */
158
+
159
+int tsend_dgram_ev(int fd, const struct iovec* v, int count, int timeout)
160
+{
161
+	TSEND_INIT;
162
+again:
163
+	n=writev(fd, v, count);
164
+	TSEND_ERR_CHECK("tsend_datagram_ev");
165
+	return n;
166
+	TSEND_POLL("tsend_datagram_ev");
167
+error:
168
+	return -1;
169
+}
170
+
Browse code

- small fix (some poll flags were not checked)

Andrei Pelinescu-Onciul authored on 27/02/2004 12:42:05
Showing 1 changed files
... ...
@@ -58,7 +58,8 @@ int tsend_stream(int fd, char* buf, unsigned int len, int timeout)
58 58
 	written=0;
59 59
 	initial_len=len;
60 60
 	pf.fd=fd;
61
-	pf.events=POLLIN;
61
+	pf.events=POLLOUT;
62
+	
62 63
 	
63 64
 again:
64 65
 	n=send(fd, buf, len,
... ...
@@ -86,7 +87,6 @@ again:
86 87
 		goto end;
87 88
 	}
88 89
 	while(1){
89
-		pf.revents=0;
90 90
 		n=poll(&pf, 1, timeout);
91 91
 		if (n<0){
92 92
 			if (errno==EINTR) continue; /* signal, ignore */
... ...
@@ -98,10 +98,17 @@ again:
98 98
 			LOG(L_ERR, "ERROR: tsend_stream: send timeout (%d)\n", timeout);
99 99
 			goto error;
100 100
 		}
101
-		if (pf.revents&POLLIN){
101
+		if (pf.revents&POLLOUT){
102 102
 			/* we can write again */
103 103
 			goto again;
104
+		}else if (pf.revents&(POLLERR|POLLHUP|POLLNVAL)){
105
+			LOG(L_ERR, "ERROR: tsend_stream: bad poll flags %x\n", 
106
+					pf.revents);
107
+			goto error;
104 108
 		}
109
+		/* if POLLIN or POLLPRI or other non-harmfull events happened,
110
+		 * continue ( although poll should never signal them since we're
111
+		 * not interested in them => we should never reach this point) */
105 112
 	}
106 113
 error:
107 114
 	return -1;
... ...
@@ -128,7 +135,7 @@ int tsend_dgram(int fd, char* buf, unsigned int len, int timeout,
128 135
 	written=0;
129 136
 	initial_len=len;
130 137
 	pf.fd=fd;
131
-	pf.events=POLLIN;
138
+	pf.events=POLLOUT;
132 139
 	
133 140
 again:
134 141
 	n=sendto(fd, buf, len, 0, to, tolen);
... ...
@@ -150,7 +157,6 @@ again:
150 157
 		goto end;
151 158
 	}
152 159
 	while(1){
153
-		pf.revents=0;
154 160
 		n=poll(&pf, 1, timeout);
155 161
 		if (n<0){
156 162
 			if (errno==EINTR) continue; /* signal, ignore */
... ...
@@ -162,10 +168,17 @@ again:
162 168
 			LOG(L_ERR, "ERROR: tsend_dgram: send timeout (%d)\n", timeout);
163 169
 			goto error;
164 170
 		}
165
-		if (pf.revents&POLLIN){
171
+		if (pf.revents&POLLOUT){
166 172
 			/* we can write again */
167 173
 			goto again;
174
+		}else if (pf.revents&(POLLERR|POLLHUP|POLLNVAL)){
175
+			LOG(L_ERR, "ERROR: tsend_dgram: bad poll flags %x\n", 
176
+					pf.revents);
177
+			goto error;
168 178
 		}
179
+		/* if POLLIN or POLLPRI or other non-harmfull events happened,
180
+		 * continue ( although poll should never signal them since we're
181
+		 * not interested in them => we should never reach this point) */
169 182
 	}
170 183
 error:
171 184
 	return -1;
Browse code

- replaced tcp_blocking_write with more generic tsend_stream(fd, buf, len, timeout) & tsend_dgram(fd, buf, len, timeout, to, tolen) so that they can be used from ser modules a.s.o.

Andrei Pelinescu-Onciul authored on 26/02/2004 18:00:49
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,176 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2001-2003 Fhg Fokus
5
+ *
6
+ * This file is part of ser, a free SIP server.
7
+ *
8
+ * ser is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation; either version 2 of the License, or
11
+ * (at your option) any later version
12
+ *
13
+ * For a license to use the ser software under conditions
14
+ * other than those described here, or to purchase support for this
15
+ * software, please contact iptel.org by e-mail at the following addresses:
16
+ *    info@iptel.org
17
+ *
18
+ * ser is distributed in the hope that it will be useful,
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
+ * GNU General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU General Public License
24
+ * along with this program; if not, write to the Free Software
25
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
+ */
27
+/*
28
+ * send with timeout for stream and datagram sockets
29
+ * 
30
+ * History:
31
+ * --------
32
+ *  2004-02-26  created by andrei
33
+ */
34
+
35
+#include <string.h>
36
+#include <errno.h>
37
+#include <sys/poll.h>
38
+
39
+#include <sys/types.h>
40
+#include <sys/socket.h>
41
+
42
+#include "dprint.h"
43
+
44
+
45
+/* sends on fd (which must be O_NONBLOCK); if it cannot send any data
46
+ * in timeout miliseconds it will return ERROR
47
+ * returns: -1 on error, or number of bytes written
48
+ *  (if less than len => couldn't send all)
49
+ *  bugs: signals will reset the timer
50
+ */
51
+int tsend_stream(int fd, char* buf, unsigned int len, int timeout)
52
+{
53
+	int n;
54
+	int written;
55
+	int initial_len;
56
+	struct pollfd pf;
57
+	
58
+	written=0;
59
+	initial_len=len;
60
+	pf.fd=fd;
61
+	pf.events=POLLIN;
62
+	
63
+again:
64
+	n=send(fd, buf, len,
65
+#ifdef HAVE_MSG_NOSIGNAL
66
+			MSG_NOSIGNAL
67
+#else
68
+			0
69
+#endif
70
+		);
71
+	if (n<0){
72
+		if (errno==EINTR) goto again;
73
+		else if (errno!=EAGAIN && errno!=EWOULDBLOCK){
74
+			LOG(L_ERR, "ERROR: tsend_stream: failed to send: (%d) %s\n",
75
+						errno, strerror(errno));
76
+			goto error;
77
+		}
78
+	}
79
+	written+=n;
80
+	if (n<len){
81
+		/* partial write */
82
+		buf+=n;
83
+		len-=n;
84
+	}else{
85
+		/* succesfull full write */
86
+		goto end;
87
+	}
88
+	while(1){
89
+		pf.revents=0;
90
+		n=poll(&pf, 1, timeout);
91
+		if (n<0){
92
+			if (errno==EINTR) continue; /* signal, ignore */
93
+			LOG(L_ERR, "ERROR: tsend_stream: poll failed: %s [%d]\n",
94
+					strerror(errno), errno);
95
+			goto error;
96
+		}else if (n==0){
97
+			/* timeout */
98
+			LOG(L_ERR, "ERROR: tsend_stream: send timeout (%d)\n", timeout);
99
+			goto error;
100
+		}
101
+		if (pf.revents&POLLIN){
102
+			/* we can write again */
103
+			goto again;
104
+		}
105
+	}
106
+error:
107
+	return -1;
108
+end:
109
+	return written;
110
+}
111
+
112
+
113
+
114
+/* sends on dram fd (which must be O_NONBLOCK); if it cannot send any data
115
+ * in timeout miliseconds it will return ERROR
116
+ * returns: -1 on error, or number of bytes written
117
+ *  (if less than len => couldn't send all)
118
+ *  bugs: signals will reset the timer
119
+ */
120
+int tsend_dgram(int fd, char* buf, unsigned int len, int timeout,
121
+				const struct sockaddr* to, socklen_t tolen)
122
+{
123
+	int n;
124
+	int written;
125
+	int initial_len;
126
+	struct pollfd pf;
127
+	
128
+	written=0;
129
+	initial_len=len;
130
+	pf.fd=fd;
131
+	pf.events=POLLIN;
132
+	
133
+again:
134
+	n=sendto(fd, buf, len, 0, to, tolen);
135
+	if (n<0){
136
+		if (errno==EINTR) goto again;
137
+		else if (errno!=EAGAIN && errno!=EWOULDBLOCK){
138
+			LOG(L_ERR, "ERROR: tsend_dgram: failed to send: (%d) %s\n",
139
+						errno, strerror(errno));
140
+			goto error;
141
+		}
142
+	}
143
+	written+=n;
144
+	if (n<len){
145
+		/* partial write */
146
+		LOG(L_CRIT, "BUG: tsend_dgram: partial write on datagram socket\n");
147
+		goto error;
148
+	}else{
149
+		/* succesfull full write */
150
+		goto end;
151
+	}
152
+	while(1){
153
+		pf.revents=0;
154
+		n=poll(&pf, 1, timeout);
155
+		if (n<0){
156