ruby-lsapi 4.2 → 5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7071cdbea2aaa5b5e3e15d81cb659dbcdd4f0ec2
4
- data.tar.gz: c224835bd8b574e1a697cbe1754a21f01bec9a5f
2
+ SHA256:
3
+ metadata.gz: bd8cc4083ffaa583379211d191ec387ebf69929bc27100fc0e6793a43186842b
4
+ data.tar.gz: d25c2dfd57b141aefedbe63d0c52c60c1bf634cf6b11876d191a8758368df4b0
5
5
  SHA512:
6
- metadata.gz: b00c35195f8785e6196f1b2ab97d3bac71ad795b7290015e5bb2f419d1a2477d44b27088d019f329d4c13ba11b672417bf78c4189a43ecb9b1465c58c60c7046
7
- data.tar.gz: a623cc9fcd25ab6ce7e6c41d50ddc8d19c5b020d23fff9ad5890483346a89ae01ab4ab466f85bef896745f74faddf7581f4a9b01c7ca8ef42122a69a36fa84cf
6
+ metadata.gz: d67f5730c65b2b42185450ffcdcb03203f5ba7952467b46cd82a6e60d530a0071b9ba22f42eee92d13adbe95d27aa705589386f2b12843a8bf4acd65c5a1c5ec
7
+ data.tar.gz: 418eef951b7d6c9880c1a7f89a64568d2073920e9edc6ba45c21c5d43278f23e8294a2062c22d28ac309f1e204924e722b32c722458991269b8ed3c192a65e4b
@@ -1,21 +1,21 @@
1
1
  /*
2
- Copyright (c) 2002-2014, Lite Speed Technologies Inc.
2
+ Copyright (c) 2002-2018, Lite Speed Technologies Inc.
3
3
  All rights reserved.
4
4
 
5
5
  Redistribution and use in source and binary forms, with or without
6
6
  modification, are permitted provided that the following conditions are
7
- met:
7
+ met:
8
8
 
9
9
  * Redistributions of source code must retain the above copyright
10
- notice, this list of conditions and the following disclaimer.
10
+ notice, this list of conditions and the following disclaimer.
11
11
  * Redistributions in binary form must reproduce the above
12
12
  copyright notice, this list of conditions and the following
13
13
  disclaimer in the documentation and/or other materials provided
14
- with the distribution.
14
+ with the distribution.
15
15
  * Neither the name of the Lite Speed Technologies Inc nor the
16
16
  names of its contributors may be used to endorse or promote
17
17
  products derived from this software without specific prior
18
- written permission.
18
+ written permission.
19
19
 
20
20
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
21
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -27,9 +27,10 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
27
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
28
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
29
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
31
  */
32
32
 
33
+
33
34
  #ifndef _LSAPIDEF_H_
34
35
  #define _LSAPIDEF_H_
35
36
 
@@ -75,7 +76,7 @@ enum
75
76
 
76
77
  /* Values for m_flag in lsapi_packet_header */
77
78
  #define LSAPI_ENDIAN_LITTLE 0
78
- #define LSAPI_ENDIAN_BIG 1
79
+ #define LSAPI_ENDIAN_BIG 1
79
80
  #define LSAPI_ENDIAN_BIT 1
80
81
 
81
82
  #if defined(__i386__)||defined( __x86_64 )||defined( __x86_64__ )
@@ -118,7 +119,7 @@ struct lsapi_packet_header
118
119
 
119
120
  /*
120
121
  LSAPI request header packet
121
-
122
+
122
123
  1. struct lsapi_req_header
123
124
  2. struct lsapi_http_header_index
124
125
  3. lsapi_header_offset * unknownHeaders
@@ -129,7 +130,7 @@ struct lsapi_packet_header
129
130
  struct lsapi_req_header
130
131
  {
131
132
  struct lsapi_packet_header m_pktHeader;
132
-
133
+
133
134
  int32_t m_httpHeaderLen;
134
135
  int32_t m_reqBodyLen;
135
136
  int32_t m_scriptFileOff; /* path to the script file. */
@@ -143,11 +144,11 @@ struct lsapi_req_header
143
144
 
144
145
 
145
146
  struct lsapi_http_header_index
146
- {
147
- int16_t m_headerLen[H_TRANSFER_ENCODING+1];
147
+ {
148
+ uint16_t m_headerLen[H_TRANSFER_ENCODING+1];
148
149
  int32_t m_headerOff[H_TRANSFER_ENCODING+1];
149
- } ;
150
-
150
+ } ;
151
+
151
152
  struct lsapi_header_offset
152
153
  {
153
154
  int32_t nameOff;
@@ -1,21 +1,22 @@
1
+ //#define LSAPI_DEBUG
1
2
  /*
2
- Copyright (c) 2002-2015, Lite Speed Technologies Inc.
3
+ Copyright (c) 2002-2018, Lite Speed Technologies Inc.
3
4
  All rights reserved.
4
5
 
5
6
  Redistribution and use in source and binary forms, with or without
6
7
  modification, are permitted provided that the following conditions are
7
- met:
8
+ met:
8
9
 
9
10
  * Redistributions of source code must retain the above copyright
10
- notice, this list of conditions and the following disclaimer.
11
+ notice, this list of conditions and the following disclaimer.
11
12
  * Redistributions in binary form must reproduce the above
12
13
  copyright notice, this list of conditions and the following
13
14
  disclaimer in the documentation and/or other materials provided
14
- with the distribution.
15
+ with the distribution.
15
16
  * Neither the name of the Lite Speed Technologies Inc nor the
16
17
  names of its contributors may be used to endorse or promote
17
18
  products derived from this software without specific prior
18
- written permission.
19
+ written permission.
19
20
 
20
21
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
22
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -27,7 +28,7 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
28
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
29
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
30
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32
  */
32
33
 
33
34
 
@@ -35,11 +36,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
36
  #include <dlfcn.h>
36
37
  #include <errno.h>
37
38
  #include <fcntl.h>
38
-
39
+ #include <limits.h>
39
40
  #include <sys/stat.h>
41
+ #include <sched.h>
40
42
  #include <signal.h>
41
43
  #include <stdlib.h>
42
44
  #include <stdio.h>
45
+ #include <stdarg.h>
43
46
  #include <string.h>
44
47
  #include <sys/mman.h>
45
48
  #include <sys/resource.h>
@@ -94,26 +97,70 @@ typedef struct lsapi_MD5Context lsapi_MD5_CTX;
94
97
  #define LSAPI_ST_REQ_BODY 2
95
98
  #define LSAPI_ST_RESP_HEADER 4
96
99
  #define LSAPI_ST_RESP_BODY 8
100
+ #define LSAPI_ST_BACKGROUND 16
97
101
 
98
102
  #define LSAPI_RESP_BUF_SIZE 8192
99
103
  #define LSAPI_INIT_RESP_HEADER_LEN 4096
100
104
 
105
+ enum
106
+ {
107
+ LSAPI_STATE_IDLE,
108
+ LSAPI_STATE_CONNECTED,
109
+ LSAPI_STATE_ACCEPTING,
110
+ };
111
+
112
+ typedef struct lsapi_child_status
113
+ {
114
+ int m_pid;
115
+ long m_tmStart;
116
+
117
+ volatile short m_iKillSent;
118
+ volatile char m_inProcess;
119
+ volatile char m_state;
120
+ volatile int m_iReqCounter;
121
+
122
+ volatile long m_tmWaitBegin;
123
+ volatile long m_tmReqBegin;
124
+ volatile long m_tmLastCheckPoint;
125
+ }
126
+ lsapi_child_status;
101
127
 
128
+ static lsapi_child_status * s_worker_status = NULL;
102
129
 
103
130
  static int g_inited = 0;
104
131
  static int g_running = 1;
105
132
  static int s_ppid;
133
+ static int s_restored_ppid = 0;
134
+ static int s_pid = 0;
106
135
  static int s_slow_req_msecs = 0;
107
136
  static int s_keepListener = 0;
108
137
  static int s_dump_debug_info = 0;
109
138
  static int s_pid_dump_debug_info = 0;
139
+ static int s_req_processed = 0;
140
+ static int s_skip_write = 0;
141
+ static int (*pthread_atfork_func)(void (*prepare)(void), void (*parent)(void),
142
+ void (*child)(void)) = NULL;
143
+
144
+ static int *s_busy_workers = NULL;
145
+ static int *s_accepting_workers = NULL;
146
+ static int *s_global_counter = &s_req_processed;
147
+ static int s_max_busy_workers = -1;
148
+ static char *s_stderr_log_path = NULL;
149
+ static int s_stderr_is_pipe = 0;
150
+ static int s_ignore_pid = -1;
151
+ static size_t s_total_pages = 1;
152
+ static size_t s_min_avail_pages = 256 * 1024;
153
+ static size_t *s_avail_pages = &s_total_pages;
110
154
 
111
- LSAPI_Request g_req = { -1, -1 };
155
+ LSAPI_Request g_req =
156
+ { .m_fdListen = -1, .m_fd = -1 };
112
157
 
113
- static char s_pSecret[24];
158
+ static char s_secret[24];
114
159
 
160
+ static LSAPI_On_Timer_pf s_proc_group_timer_cb = NULL;
115
161
 
116
162
  void Flush_RespBuf_r( LSAPI_Request * pReq );
163
+ static int lsapi_reopen_stderr(const char *p);
117
164
 
118
165
  static const char *CGI_HEADERS[H_TRANSFER_ENCODING+1] =
119
166
  {
@@ -135,7 +182,7 @@ static const char *CGI_HEADERS[H_TRANSFER_ENCODING+1] =
135
182
  "HTTP_VIA",
136
183
  "HTTP_TRANSFER_ENCODING"
137
184
  };
138
-
185
+
139
186
  static int CGI_HEADER_LEN[H_TRANSFER_ENCODING+1] =
140
187
  { 11, 19, 20, 20, 18, 15, 12, 14, 11, 12, 9, 11, 12, 15, 18,
141
188
  22, 13, 18, 13, 24, 15, 10, 20, 8, 22 };
@@ -166,10 +213,102 @@ static int HTTP_HEADER_LEN[H_TRANSFER_ENCODING+1] =
166
213
  { 6, 14, 15, 15, 13, 10, 12, 14, 6, 7, 4, 6, 7, 10, //user-agent
167
214
  13,17, 8, 13, 8, 19, 10, 5, 15, 3, 17
168
215
  };
169
-
216
+
217
+
218
+ static const char *s_log_level_names[8] =
219
+ {
220
+ "", "DEBUG","INFO", "NOTICE", "WARN", "ERROR", "CRIT", "FATAL"
221
+ };
222
+
223
+
224
+ void LSAPI_Log(int flag, const char * fmt, ...)
225
+ {
226
+ char buf[1024];
227
+ char *p = buf;
228
+ if ((flag & LSAPI_LOG_TIMESTAMP_BITS)
229
+ && !(s_stderr_is_pipe))
230
+ {
231
+ struct timeval tv;
232
+ struct tm tm;
233
+ gettimeofday(&tv, NULL);
234
+ localtime_r(&tv.tv_sec, &tm);
235
+ if (flag & LSAPI_LOG_TIMESTAMP_FULL)
236
+ {
237
+ p += snprintf(p, 1024, "%04d-%02d-%02d %02d:%02d:%02d.%06d ",
238
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
239
+ tm.tm_hour, tm.tm_min, tm.tm_sec, (int)tv.tv_usec);
240
+ }
241
+ else if (flag & LSAPI_LOG_TIMESTAMP_HMS)
242
+ {
243
+ p += snprintf(p, 1024, "%02d:%02d:%02d ",
244
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
245
+ }
246
+ }
247
+
248
+ int level = flag & LSAPI_LOG_LEVEL_BITS;
249
+ if (level && level <= LSAPI_LOG_FLAG_FATAL)
250
+ {
251
+ p += snprintf(p, 100, "[%s] ", s_log_level_names[level]);
252
+ }
253
+
254
+ if (flag & LSAPI_LOG_PID)
255
+ {
256
+ p += snprintf(p, 100, "[UID:%d][%d] ", getuid(), s_pid);
257
+ }
258
+
259
+ if (p > buf)
260
+ fprintf(stderr, "%.*s", (int)(p - buf), buf);
261
+ va_list ap;
262
+ va_start(ap, fmt);
263
+ vfprintf(stderr, fmt, ap);
264
+ va_end(ap);
265
+ }
266
+
267
+ #ifdef LSAPI_DEBUG
268
+
269
+ #define DBGLOG_FLAG (LSAPI_LOG_TIMESTAMP_FULL|LSAPI_LOG_FLAG_DEBUG|LSAPI_LOG_PID)
270
+ #define lsapi_dbg(...) LSAPI_Log(DBGLOG_FLAG, __VA_ARGS__)
271
+
272
+ #else
273
+
274
+ #define lsapi_dbg(...)
275
+
276
+ #endif
277
+
278
+ #define lsapi_log(...) LSAPI_Log(LSAPI_LOG_TIMESTAMP_FULL|LSAPI_LOG_PID, __VA_ARGS__)
279
+
280
+
281
+ void lsapi_perror(const char * pMessage, int err_no)
282
+ {
283
+ lsapi_log("%s, errno: %d (%s)\n", pMessage, err_no, strerror(err_no));
284
+ }
285
+
286
+
287
+ static int lsapi_parent_dead()
288
+ {
289
+ // Return non-zero if the parent is dead. 0 if still alive.
290
+ if (!s_ppid) {
291
+ // not checking, so not dead
292
+ return(0);
293
+ }
294
+ if (s_restored_ppid) {
295
+ if (kill(s_restored_ppid,0) == -1) {
296
+ if (errno == EPERM) {
297
+ return(0); // no permission, but it's still there.
298
+ }
299
+ return(1); // Dead
300
+ }
301
+ return(0); // it worked, so it's not dead
302
+ }
303
+ return(s_ppid != getppid());
304
+ }
305
+
306
+
170
307
  static void lsapi_sigpipe( int sig )
171
308
  {
172
309
  }
310
+
311
+
173
312
  static void lsapi_siguser1( int sig )
174
313
  {
175
314
  g_running = 0;
@@ -178,7 +317,7 @@ static void lsapi_siguser1( int sig )
178
317
  #ifndef sighandler_t
179
318
  typedef void (*sighandler_t)(int);
180
319
  #endif
181
-
320
+
182
321
  static void lsapi_signal(int signo, sighandler_t handler)
183
322
  {
184
323
  struct sigaction sa;
@@ -196,12 +335,12 @@ static void lsapi_signal(int signo, sighandler_t handler)
196
335
 
197
336
 
198
337
  static int s_enable_core_dump = 0;
199
- static void lsapi_enable_core_dump()
338
+ static void lsapi_enable_core_dump(void)
200
339
  {
201
340
  #if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__) \
202
341
  || defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
203
342
  int mib[2];
204
- size_t len;
343
+ size_t len;
205
344
 
206
345
  len = 2;
207
346
  if ( sysctlnametomib("kern.sugid_coredump", mib, &len) == 0 )
@@ -212,7 +351,7 @@ static void lsapi_enable_core_dump()
212
351
  "core dump may not be available!");
213
352
  }
214
353
 
215
-
354
+
216
355
  #endif
217
356
 
218
357
  #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
@@ -233,6 +372,7 @@ static inline void lsapi_buildPacketHeader( struct lsapi_packet_header * pHeader
233
372
  pHeader->m_packetLen.m_iLen = len;
234
373
  }
235
374
 
375
+
236
376
  static int lsapi_set_nblock( int fd, int nonblock )
237
377
  {
238
378
  int val = fcntl( fd, F_GETFL, 0 );
@@ -253,6 +393,7 @@ static int lsapi_set_nblock( int fd, int nonblock )
253
393
  return 0;
254
394
  }
255
395
 
396
+
256
397
  static int lsapi_close( int fd )
257
398
  {
258
399
  int ret;
@@ -265,6 +406,20 @@ static int lsapi_close( int fd )
265
406
  }
266
407
  }
267
408
 
409
+
410
+ static void lsapi_close_connection(LSAPI_Request *pReq)
411
+ {
412
+ if (pReq->m_fd == -1)
413
+ return;
414
+ lsapi_close(pReq->m_fd);
415
+ pReq->m_fd = -1;
416
+ if (s_busy_workers)
417
+ __sync_fetch_and_sub(s_busy_workers, 1);
418
+ if (s_worker_status)
419
+ __sync_lock_test_and_set(&s_worker_status->m_state, LSAPI_STATE_IDLE);
420
+ }
421
+
422
+
268
423
  static inline ssize_t lsapi_read( int fd, void * pBuf, size_t len )
269
424
  {
270
425
  ssize_t ret;
@@ -277,6 +432,7 @@ static inline ssize_t lsapi_read( int fd, void * pBuf, size_t len )
277
432
  }
278
433
  }
279
434
 
435
+
280
436
  /*
281
437
  static int lsapi_write( int fd, const void * pBuf, int len )
282
438
  {
@@ -299,11 +455,16 @@ static int lsapi_write( int fd, const void * pBuf, int len )
299
455
  }
300
456
  */
301
457
 
458
+
302
459
  static int lsapi_writev( int fd, struct iovec ** pVec, int count, int totalLen )
303
460
  {
304
461
  int ret;
305
462
  int left = totalLen;
306
463
  int n = count;
464
+
465
+ if (s_skip_write)
466
+ return totalLen;
467
+
307
468
  while(( left > 0 )&&g_running )
308
469
  {
309
470
  ret = writev( fd, *pVec, n );
@@ -343,6 +504,7 @@ static int lsapi_writev( int fd, struct iovec ** pVec, int count, int totalLen )
343
504
  return totalLen - left;
344
505
  }
345
506
 
507
+
346
508
  /*
347
509
  static int getTotalLen( struct iovec * pVec, int count )
348
510
  {
@@ -357,6 +519,7 @@ static int getTotalLen( struct iovec * pVec, int count )
357
519
  }
358
520
  */
359
521
 
522
+
360
523
  static inline int allocateBuf( LSAPI_Request * pReq, int size )
361
524
  {
362
525
  char * pBuf = (char *)realloc( pReq->m_pReqBuf, size );
@@ -384,6 +547,7 @@ static int allocateIovec( LSAPI_Request * pReq, int n )
384
547
  return 0;
385
548
  }
386
549
 
550
+
387
551
  static int allocateRespHeaderBuf( LSAPI_Request * pReq, int size )
388
552
  {
389
553
  char * p = (char *)realloc( pReq->m_pRespHeaderBuf, size );
@@ -415,11 +579,12 @@ static inline int verifyHeader( struct lsapi_packet_header * pHeader, char pktTy
415
579
  return pHeader->m_packetLen.m_iLen;
416
580
  }
417
581
 
582
+
418
583
  static int allocateEnvList( struct LSAPI_key_value_pair ** pEnvList,
419
584
  int *curSize, int newSize )
420
585
  {
421
586
  struct LSAPI_key_value_pair * pBuf;
422
- if ( *curSize >= newSize )
587
+ if ( *curSize >= newSize )
423
588
  return 0;
424
589
  if ( newSize > 8192 )
425
590
  return -1;
@@ -436,6 +601,7 @@ static int allocateEnvList( struct LSAPI_key_value_pair ** pEnvList,
436
601
 
437
602
  }
438
603
 
604
+
439
605
  static inline int isPipe( int fd )
440
606
  {
441
607
  char achPeer[128];
@@ -447,6 +613,7 @@ static inline int isPipe( int fd )
447
613
  return 1;
448
614
  }
449
615
 
616
+
450
617
  static int parseEnv( struct LSAPI_key_value_pair * pEnvList, int count,
451
618
  char **pBegin, char * pEnd )
452
619
  {
@@ -483,6 +650,7 @@ static int parseEnv( struct LSAPI_key_value_pair * pEnvList, int count,
483
650
  return 0;
484
651
  }
485
652
 
653
+
486
654
  static inline void swapIntEndian( int * pInteger )
487
655
  {
488
656
  char * p = (char *)pInteger;
@@ -493,9 +661,10 @@ static inline void swapIntEndian( int * pInteger )
493
661
  b = p[1];
494
662
  p[1] = p[2];
495
663
  p[2] = b;
496
-
664
+
497
665
  }
498
666
 
667
+
499
668
  static inline void fixEndian( LSAPI_Request * pReq )
500
669
  {
501
670
  struct lsapi_req_header *p= pReq->m_pHeader;
@@ -510,6 +679,7 @@ static inline void fixEndian( LSAPI_Request * pReq )
510
679
  swapIntEndian( &p->m_cntSpecialEnv );
511
680
  }
512
681
 
682
+
513
683
  static void fixHeaderIndexEndian( LSAPI_Request * pReq )
514
684
  {
515
685
  int i;
@@ -541,6 +711,40 @@ static void fixHeaderIndexEndian( LSAPI_Request * pReq )
541
711
  }
542
712
  }
543
713
 
714
+
715
+ static int validateHeaders( LSAPI_Request * pReq )
716
+ {
717
+ int totalLen = pReq->m_pHeader->m_httpHeaderLen;
718
+ int i;
719
+ for(i = 0; i < H_TRANSFER_ENCODING; ++i)
720
+ {
721
+ if ( pReq->m_pHeaderIndex->m_headerOff[i] )
722
+ {
723
+ if (pReq->m_pHeaderIndex->m_headerOff[i] > totalLen
724
+ || pReq->m_pHeaderIndex->m_headerLen[i]
725
+ + pReq->m_pHeaderIndex->m_headerOff[i] > totalLen)
726
+ return -1;
727
+ }
728
+ }
729
+ if (pReq->m_pHeader->m_cntUnknownHeaders > 0)
730
+ {
731
+ struct lsapi_header_offset * pCur, *pEnd;
732
+ pCur = pReq->m_pUnknownHeader;
733
+ pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders;
734
+ while( pCur < pEnd )
735
+ {
736
+ if (pCur->nameOff > totalLen
737
+ || pCur->nameOff + pCur->nameLen > totalLen
738
+ || pCur->valueOff > totalLen
739
+ || pCur->valueOff + pCur->valueLen > totalLen)
740
+ return -1;
741
+ ++pCur;
742
+ }
743
+ }
744
+ return 0;
745
+ }
746
+
747
+
544
748
  static uid_t s_uid = 0;
545
749
  static uid_t s_defaultUid; //web server need set this
546
750
  static gid_t s_defaultGid;
@@ -562,23 +766,23 @@ static int (*fp_lve_destroy)(struct liblve *) = NULL;
562
766
  static int (*fp_lve_enter)(struct liblve *, uint32_t, int32_t, int32_t, uint32_t *) = NULL;
563
767
  static int (*fp_lve_leave)(struct liblve *, uint32_t *) = NULL;
564
768
  static int (*fp_lve_jail)( struct passwd *, char *) = NULL;
565
- static int lsapi_load_lve_lib()
769
+ static int lsapi_load_lve_lib(void)
566
770
  {
567
- s_liblve = dlopen("liblve.so.0", RTLD_LAZY);
771
+ s_liblve = dlopen("liblve.so.0", RTLD_NOW | RTLD_GLOBAL);
568
772
  if (s_liblve)
569
773
  {
570
774
  fp_lve_is_available = dlsym(s_liblve, "lve_is_available");
571
- if (dlerror() == NULL)
775
+ if (dlerror() == NULL)
572
776
  {
573
777
  if ( !(*fp_lve_is_available)() )
574
778
  {
575
779
  int uid = getuid();
576
780
  if ( uid )
577
781
  {
578
- setreuid( s_uid, uid );
782
+ if (setreuid( s_uid, uid )) {};
579
783
  if ( !(*fp_lve_is_available)() )
580
784
  s_enable_lve = 0;
581
- setreuid( uid, s_uid );
785
+ if (setreuid( uid, s_uid )) {};
582
786
  }
583
787
  }
584
788
  }
@@ -590,11 +794,12 @@ static int lsapi_load_lve_lib()
590
794
  return (s_liblve)? 0 : -1;
591
795
  }
592
796
 
593
- static int init_lve_ex()
797
+
798
+ static int init_lve_ex(void)
594
799
  {
595
800
  int rc;
596
801
  if ( !s_liblve )
597
- return -1;
802
+ return -1;
598
803
  fp_lve_instance_init = dlsym(s_liblve, "lve_instance_init");
599
804
  fp_lve_destroy = dlsym(s_liblve, "lve_destroy");
600
805
  fp_lve_enter = dlsym(s_liblve, "lve_enter");
@@ -602,13 +807,13 @@ static int init_lve_ex()
602
807
  if ( s_enable_lve >= LSAPI_CAGEFS_ENABLED )
603
808
  fp_lve_jail = dlsym(s_liblve, "jail" );
604
809
 
605
- if ( s_lve == NULL )
810
+ if ( s_lve == NULL )
606
811
  {
607
812
  rc = (*fp_lve_instance_init)(NULL);
608
813
  s_lve = malloc(rc);
609
814
  }
610
815
  rc = (*fp_lve_instance_init)(s_lve);
611
- if (rc != 0)
816
+ if (rc != 0)
612
817
  {
613
818
  perror( "LSAPI: Unable to initialize LVE" );
614
819
  free( s_lve );
@@ -616,7 +821,7 @@ static int init_lve_ex()
616
821
  return -1;
617
822
  }
618
823
  return 0;
619
-
824
+
620
825
  }
621
826
 
622
827
  #endif
@@ -629,32 +834,32 @@ static int readSecret( const char * pSecretFile )
629
834
  int fd = open( pSecretFile, O_RDONLY , 0600 );
630
835
  if ( fd == -1 )
631
836
  {
632
- fprintf( stderr, "LSAPI: failed to open secret file: %s!\n", pSecretFile );
837
+ lsapi_log("LSAPI: failed to open secret file: %s!\n", pSecretFile );
633
838
  return -1;
634
839
  }
635
840
  if ( fstat( fd, &st ) == -1 )
636
841
  {
637
- fprintf( stderr, "LSAPI: failed to check state of file: %s!\n", pSecretFile );
842
+ lsapi_log("LSAPI: failed to check state of file: %s!\n", pSecretFile );
638
843
  close( fd );
639
844
  return -1;
640
845
  }
641
846
  /*
642
847
  if ( st.st_uid != s_uid )
643
848
  {
644
- fprintf( stderr, "LSAPI: file owner check failure: %s!\n", pSecretFile );
849
+ lsapi_log("LSAPI: file owner check failure: %s!\n", pSecretFile );
645
850
  close( fd );
646
851
  return -1;
647
852
  }
648
853
  */
649
854
  if ( st.st_mode & 0077 )
650
855
  {
651
- fprintf( stderr, "LSAPI: file permission check failure: %s\n", pSecretFile );
856
+ lsapi_log("LSAPI: file permission check failure: %s\n", pSecretFile );
652
857
  close( fd );
653
858
  return -1;
654
859
  }
655
- if ( read( fd, s_pSecret, 16 ) < 16 )
860
+ if ( read( fd, s_secret, 16 ) < 16 )
656
861
  {
657
- fprintf( stderr, "LSAPI: failed to read secret from secret file: %s\n", pSecretFile );
862
+ lsapi_log("LSAPI: failed to read secret from secret file: %s\n", pSecretFile );
658
863
  close( fd );
659
864
  return -1;
660
865
  }
@@ -662,28 +867,35 @@ static int readSecret( const char * pSecretFile )
662
867
  return 0;
663
868
  }
664
869
 
665
- int LSAPI_is_suEXEC_Daemon()
870
+
871
+ int LSAPI_is_suEXEC_Daemon(void)
666
872
  {
667
- if (( !s_uid )&&( s_pSecret[0] ))
873
+ if (( !s_uid )&&( s_secret[0] ))
668
874
  return 1;
669
875
  else
670
876
  return 0;
671
877
  }
672
878
 
879
+
673
880
  static int LSAPI_perror_r( LSAPI_Request * pReq, const char * pErr1, const char *pErr2 )
674
881
  {
675
- char achError[1024];
676
- int n = snprintf(achError, 1024, "%s:%s: %s\n", pErr1, (pErr2)?pErr2:"", strerror( errno ) );
882
+ char achError[4096];
883
+ int n = snprintf(achError, sizeof(achError), "[UID:%d][%d] %s:%s: %s\n",
884
+ getuid(), getpid(),
885
+ pErr1, (pErr2)?pErr2:"", strerror(errno));
886
+ if (n > (int)sizeof(achError))
887
+ n = sizeof(achError);
677
888
  if ( pReq )
678
889
  LSAPI_Write_Stderr_r( pReq, achError, n );
679
890
  else
680
- write( STDERR_FILENO, achError, n );
891
+ if (write( STDERR_FILENO, achError, n )) {};
681
892
  return 0;
682
893
  }
683
894
 
895
+
684
896
  static int lsapi_lve_error( LSAPI_Request * pReq )
685
897
  {
686
- static const char * headers[] =
898
+ static const char * headers[] =
687
899
  {
688
900
  "Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0",
689
901
  "Pragma: no-cache",
@@ -699,11 +911,12 @@ static int lsapi_lve_error( LSAPI_Request * pReq )
699
911
  "Please try again later.\n"
700
912
  "<HR>\n"
701
913
  "</BODY></HTML>\n";
702
-
914
+
703
915
  LSAPI_ErrResponse_r( pReq, 508, headers, achBody, sizeof( achBody ) - 1 );
704
916
  return 0;
705
917
  }
706
918
 
919
+
707
920
  static int lsapi_enterLVE( LSAPI_Request * pReq, uid_t uid )
708
921
  {
709
922
  #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
@@ -714,7 +927,7 @@ static int lsapi_enterLVE( LSAPI_Request * pReq, uid_t uid )
714
927
  ret = (*fp_lve_enter)(s_lve, uid, -1, -1, &cookie);
715
928
  if ( ret < 0 )
716
929
  {
717
- fprintf( stderr, "Pid (%d): enter LVE (%d) : ressult: %d !\n", getpid(), uid, ret );
930
+ //lsapi_log("enter LVE (%d) : ressult: %d !\n", uid, ret );
718
931
  LSAPI_perror_r(pReq, "LSAPI: lve_enter() failure, reached resource limit.", NULL );
719
932
  lsapi_lve_error( pReq );
720
933
  return -1;
@@ -725,6 +938,7 @@ static int lsapi_enterLVE( LSAPI_Request * pReq, uid_t uid )
725
938
  return 0;
726
939
  }
727
940
 
941
+
728
942
  static int lsapi_jailLVE( LSAPI_Request * pReq, uid_t uid, struct passwd * pw )
729
943
  {
730
944
  int ret = 0;
@@ -733,8 +947,8 @@ static int lsapi_jailLVE( LSAPI_Request * pReq, uid_t uid, struct passwd * pw )
733
947
  ret = (*fp_lve_jail)( pw, error_msg );
734
948
  if ( ret < 0 )
735
949
  {
736
- fprintf( stderr, "LSAPI (%d): LVE jail(%d) ressult: %d, error: %s !\n",
737
- getpid(), uid, ret, error_msg );
950
+ lsapi_log("LSAPI: LVE jail(%d) ressult: %d, error: %s !\n",
951
+ uid, ret, error_msg );
738
952
  LSAPI_perror_r( pReq, "LSAPI: jail() failure.", NULL );
739
953
  return -1;
740
954
  }
@@ -744,7 +958,7 @@ static int lsapi_jailLVE( LSAPI_Request * pReq, uid_t uid, struct passwd * pw )
744
958
 
745
959
 
746
960
  #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
747
- static int lsapi_initLVE()
961
+ static int lsapi_initLVE(void)
748
962
  {
749
963
  const char * pEnv;
750
964
  if ( (pEnv = getenv( "LSAPI_LVE_ENABLE" ))!= NULL )
@@ -778,7 +992,7 @@ static int setUID_LVE(LSAPI_Request * pReq, uid_t uid, gid_t gid, const char * p
778
992
  pw = getpwuid( uid );
779
993
  #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
780
994
  if ( s_lve )
781
- {
995
+ {
782
996
  if( lsapi_enterLVE( pReq, uid ) == -1 )
783
997
  return -1;
784
998
  if ( pw && fp_lve_jail)
@@ -795,7 +1009,7 @@ static int setUID_LVE(LSAPI_Request * pReq, uid_t uid, gid_t gid, const char * p
795
1009
  }
796
1010
  }
797
1011
  #endif
798
- //if ( !uid || !gid ) //do not allow root
1012
+ //if ( !uid || !gid ) //do not allow root
799
1013
  //{
800
1014
  // return -1;
801
1015
  //}
@@ -851,7 +1065,7 @@ static int setUID_LVE(LSAPI_Request * pReq, uid_t uid, gid_t gid, const char * p
851
1065
  return 0;
852
1066
  }
853
1067
 
854
- static int lsapi_suexec_auth( LSAPI_Request *pReq,
1068
+ static int lsapi_suexec_auth( LSAPI_Request *pReq,
855
1069
  char * pAuth, int len, char * pUgid, int ugidLen )
856
1070
  {
857
1071
  lsapi_MD5_CTX md5ctx;
@@ -859,7 +1073,7 @@ static int lsapi_suexec_auth( LSAPI_Request *pReq,
859
1073
  if ( len < 32 )
860
1074
  return -1;
861
1075
  memmove( achMD5, pAuth + 16, 16 );
862
- memmove( pAuth + 16, s_pSecret, 16 );
1076
+ memmove( pAuth + 16, s_secret, 16 );
863
1077
  lsapi_MD5Init( &md5ctx );
864
1078
  lsapi_MD5Update( &md5ctx, (unsigned char *)pAuth, 32 );
865
1079
  lsapi_MD5Update( &md5ctx, (unsigned char *)pUgid, 8 );
@@ -874,7 +1088,8 @@ static int lsapi_changeUGid( LSAPI_Request * pReq )
874
1088
  {
875
1089
  int uid = s_defaultUid;
876
1090
  int gid = s_defaultGid;
877
- const char * pChroot = NULL;
1091
+ const char *pStderrLog;
1092
+ const char *pChroot = NULL;
878
1093
  struct LSAPI_key_value_pair * pEnv;
879
1094
  struct LSAPI_key_value_pair * pAuth;
880
1095
  int i;
@@ -883,7 +1098,7 @@ static int lsapi_changeUGid( LSAPI_Request * pReq )
883
1098
  //with special ID 0x00
884
1099
  //authenticate the suEXEC request;
885
1100
  //first one should be MD5( nonce + lscgid secret )
886
- //remember to clear the secret after verification
1101
+ //remember to clear the secret after verification
887
1102
  //it should be set at the end of special env
888
1103
  i = pReq->m_pHeader->m_cntSpecialEnv - 1;
889
1104
  if ( i >= 0 )
@@ -899,29 +1114,29 @@ static int lsapi_changeUGid( LSAPI_Request * pReq )
899
1114
  {
900
1115
  --pReq->m_pHeader->m_cntSpecialEnv;
901
1116
  uid = *(uint32_t *)pEnv->pValue;
902
- gid = *(((uint32_t *)pEnv->pValue) + 1 );
903
- //fprintf( stderr, "LSAPI: SUEXEC_UGID set UID: %d, GID: %d\n", uid, gid );
1117
+ gid = *(((uint32_t *)pEnv->pValue) + 1 );
1118
+ //lsapi_log("LSAPI: SUEXEC_UGID set UID: %d, GID: %d\n", uid, gid );
904
1119
  }
905
1120
  else
906
1121
  {
907
- fprintf( stderr, "LSAPI: missing SUEXEC_UGID env, use default user!\n" );
1122
+ lsapi_log("LSAPI: missing SUEXEC_UGID env, use default user!\n" );
908
1123
  pEnv = NULL;
909
1124
  }
910
1125
  if ( pEnv&& lsapi_suexec_auth( pReq, pAuth->pValue, pAuth->valLen, pEnv->pValue, pEnv->valLen ) == 0 )
911
1126
  {
912
- //read UID, GID from specialEnv
913
-
1127
+ //read UID, GID from specialEnv
1128
+
914
1129
  }
915
1130
  else
916
1131
  {
917
1132
  //authentication error
918
- fprintf( stderr, "LSAPI: SUEXEC_AUTH authentication failed, use default user!\n" );
1133
+ lsapi_log("LSAPI: SUEXEC_AUTH authentication failed, use default user!\n" );
919
1134
  uid = 0;
920
1135
  }
921
1136
  }
922
1137
  else
923
1138
  {
924
- //fprintf( stderr, "LSAPI: no SUEXEC_AUTH env, use default user!\n" );
1139
+ //lsapi_log("LSAPI: no SUEXEC_AUTH env, use default user!\n" );
925
1140
  }
926
1141
  }
927
1142
 
@@ -938,12 +1153,23 @@ static int lsapi_changeUGid( LSAPI_Request * pReq )
938
1153
  return -1;
939
1154
  }
940
1155
 
941
- s_uid = uid;
1156
+ s_uid = uid;
1157
+
1158
+ if ( pReq->m_fdListen != -1 )
1159
+ {
1160
+ close( pReq->m_fdListen );
1161
+ pReq->m_fdListen = -1;
1162
+ }
1163
+
1164
+ pStderrLog = LSAPI_GetEnv_r( pReq, "LSAPI_STDERR_LOG");
1165
+ if (pStderrLog)
1166
+ lsapi_reopen_stderr(pStderrLog);
942
1167
 
943
1168
  return 0;
944
-
1169
+
945
1170
  }
946
1171
 
1172
+
947
1173
  static int parseContentLenFromHeader(LSAPI_Request * pReq)
948
1174
  {
949
1175
  const char * pContentLen = LSAPI_GetHeader_r( pReq, H_CONTENT_LENGTH );
@@ -981,12 +1207,23 @@ static int parseRequest( LSAPI_Request * pReq, int totalLen )
981
1207
  if ( parseEnv( pReq->m_pEnvList, pReq->m_pHeader->m_cntEnv,
982
1208
  &pBegin, pEnd ) == -1 )
983
1209
  return -1;
984
-
1210
+ if (pReq->m_pHeader->m_scriptFileOff < 0
1211
+ || pReq->m_pHeader->m_scriptFileOff >= totalLen
1212
+ || pReq->m_pHeader->m_scriptNameOff < 0
1213
+ || pReq->m_pHeader->m_scriptNameOff >= totalLen
1214
+ || pReq->m_pHeader->m_queryStringOff < 0
1215
+ || pReq->m_pHeader->m_queryStringOff >= totalLen
1216
+ || pReq->m_pHeader->m_requestMethodOff < 0
1217
+ || pReq->m_pHeader->m_requestMethodOff >= totalLen)
1218
+ {
1219
+ lsapi_log("Bad request header - ERROR#1\n");
1220
+ return -1;
1221
+ }
985
1222
  pReq->m_pScriptFile = pReq->m_pReqBuf + pReq->m_pHeader->m_scriptFileOff;
986
1223
  pReq->m_pScriptName = pReq->m_pReqBuf + pReq->m_pHeader->m_scriptNameOff;
987
1224
  pReq->m_pQueryString = pReq->m_pReqBuf + pReq->m_pHeader->m_queryStringOff;
988
1225
  pReq->m_pRequestMethod = pReq->m_pReqBuf + pReq->m_pHeader->m_requestMethodOff;
989
-
1226
+
990
1227
  pBegin = pReq->m_pReqBuf + (( pBegin - pReq->m_pReqBuf + 7 ) & (~0x7));
991
1228
  pReq->m_pHeaderIndex = ( struct lsapi_http_header_index * )pBegin;
992
1229
  pBegin += sizeof( struct lsapi_http_header_index );
@@ -999,23 +1236,31 @@ static int parseRequest( LSAPI_Request * pReq, int totalLen )
999
1236
  pBegin += pReq->m_pHeader->m_httpHeaderLen;
1000
1237
  if ( pBegin != pEnd )
1001
1238
  {
1002
- fprintf( stderr, "%d: request header does match total size, total: %d, real: %ld\n", getpid(), totalLen,
1003
- pBegin - pReq->m_pReqBuf );
1239
+ lsapi_log("Request header does match total size, total: %d, "
1240
+ "real: %ld\n", totalLen, pBegin - pReq->m_pReqBuf );
1004
1241
  return -1;
1005
1242
  }
1006
1243
  if ( shouldFixEndian )
1007
1244
  {
1008
1245
  fixHeaderIndexEndian( pReq );
1009
1246
  }
1247
+
1248
+ if (validateHeaders(pReq) == -1)
1249
+ {
1250
+ lsapi_log("Bad request header - ERROR#2\n");
1251
+ return -1;
1252
+ }
1253
+
1010
1254
  pReq->m_reqBodyLen = pReq->m_pHeader->m_reqBodyLen;
1011
1255
  if ( pReq->m_reqBodyLen == -2 )
1012
1256
  {
1013
1257
  parseContentLenFromHeader(pReq);
1014
1258
  }
1015
-
1259
+
1016
1260
  return 0;
1017
1261
  }
1018
1262
 
1263
+
1019
1264
  //OPTIMIZATION
1020
1265
  static char s_accept_notify = 0;
1021
1266
  static char s_schedule_notify = 0;
@@ -1024,27 +1269,42 @@ static char s_notified_pid = 0;
1024
1269
 
1025
1270
  static struct lsapi_packet_header s_ack = {'L', 'S',
1026
1271
  LSAPI_REQ_RECEIVED, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} };
1272
+ static struct lsapi_packet_header s_conn_close_pkt = {'L', 'S',
1273
+ LSAPI_CONN_CLOSE, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} };
1274
+
1027
1275
 
1028
-
1029
- static inline int write_req_received_notification( int fd )
1276
+ static inline int send_notification_pkt( int fd, struct lsapi_packet_header *pkt )
1030
1277
  {
1031
- if ( write( fd, &s_ack, LSAPI_PACKET_HEADER_LEN )
1032
- < LSAPI_PACKET_HEADER_LEN )
1278
+ if ( write( fd, pkt, LSAPI_PACKET_HEADER_LEN ) < LSAPI_PACKET_HEADER_LEN )
1033
1279
  return -1;
1034
1280
  return 0;
1035
1281
  }
1036
1282
 
1037
- static void lsapi_sigalarm( int sig )
1283
+
1284
+ static inline int send_req_received_notification( int fd )
1038
1285
  {
1039
- if ( s_notify_scheduled )
1040
- {
1041
- s_notify_scheduled = 0;
1042
- if ( g_req.m_fd != -1 )
1043
- write_req_received_notification( g_req.m_fd );
1044
- }
1286
+ return send_notification_pkt(fd, &s_ack);
1287
+ }
1288
+
1289
+
1290
+ static inline int send_conn_close_notification( int fd )
1291
+ {
1292
+ return send_notification_pkt(fd, &s_conn_close_pkt);
1045
1293
  }
1046
1294
 
1047
- static inline int lsapi_schedule_notify()
1295
+
1296
+ //static void lsapi_sigalarm( int sig )
1297
+ //{
1298
+ // if ( s_notify_scheduled )
1299
+ // {
1300
+ // s_notify_scheduled = 0;
1301
+ // if ( g_req.m_fd != -1 )
1302
+ // write_req_received_notification( g_req.m_fd );
1303
+ // }
1304
+ //}
1305
+
1306
+
1307
+ static inline int lsapi_schedule_notify(void)
1048
1308
  {
1049
1309
  if ( !s_notify_scheduled )
1050
1310
  {
@@ -1054,11 +1314,12 @@ static inline int lsapi_schedule_notify()
1054
1314
  return 0;
1055
1315
  }
1056
1316
 
1317
+
1057
1318
  static inline int notify_req_received( int fd )
1058
1319
  {
1059
1320
  if ( s_schedule_notify )
1060
1321
  return lsapi_schedule_notify();
1061
- return write_req_received_notification( fd );
1322
+ return send_req_received_notification( fd );
1062
1323
 
1063
1324
  }
1064
1325
 
@@ -1070,12 +1331,13 @@ static inline int lsapi_notify_pid( int fd )
1070
1331
  8 + LSAPI_PACKET_HEADER_LEN );
1071
1332
  memmove( &achBuf[8], "\0PID", 4 );
1072
1333
  *((int *)&achBuf[12]) = getpid();
1073
-
1334
+
1074
1335
  if ( write( fd, achBuf, 16 ) < 16 )
1075
1336
  return -1;
1076
1337
  return 0;
1077
1338
  }
1078
1339
 
1340
+
1079
1341
  static char s_conn_key_packet[16];
1080
1342
  static inline int init_conn_key( int fd )
1081
1343
  {
@@ -1094,10 +1356,11 @@ static inline int init_conn_key( int fd )
1094
1356
  < LSAPI_PACKET_HEADER_LEN+8 )
1095
1357
  return -1;
1096
1358
  return 0;
1097
-
1359
+
1098
1360
 
1099
1361
  }
1100
1362
 
1363
+
1101
1364
  static int readReq( LSAPI_Request * pReq )
1102
1365
  {
1103
1366
  int len;
@@ -1122,12 +1385,12 @@ static int readReq( LSAPI_Request * pReq )
1122
1385
  packetLen = verifyHeader( &pReq->m_pHeader->m_pktHeader, LSAPI_BEGIN_REQUEST );
1123
1386
  if ( packetLen < 0 )
1124
1387
  {
1125
- fprintf( stderr, "%d: packetLen < 0\n", getpid() );
1388
+ lsapi_log("packetLen < 0\n");
1126
1389
  return -1;
1127
1390
  }
1128
1391
  if ( packetLen > LSAPI_MAX_HEADER_LEN )
1129
1392
  {
1130
- fprintf( stderr, "%d: packetLen > %d\n", getpid(), LSAPI_MAX_HEADER_LEN );
1393
+ lsapi_log("packetLen > %d\n", LSAPI_MAX_HEADER_LEN );
1131
1394
  return -1;
1132
1395
  }
1133
1396
 
@@ -1145,15 +1408,18 @@ static int readReq( LSAPI_Request * pReq )
1145
1408
  }
1146
1409
  if ( parseRequest( pReq, packetLen ) < 0 )
1147
1410
  {
1148
- fprintf( stderr, "%d: parseRequest error\n", getpid() );
1411
+ lsapi_log("ParseRequest error\n");
1149
1412
  return -1;
1150
1413
  }
1151
1414
 
1152
1415
  pReq->m_reqState = LSAPI_ST_REQ_BODY | LSAPI_ST_RESP_HEADER;
1153
1416
 
1154
1417
  if ( !s_uid )
1418
+ {
1155
1419
  if ( lsapi_changeUGid( pReq ) )
1156
1420
  return -1;
1421
+ memset(s_secret, 0, sizeof(s_secret));
1422
+ }
1157
1423
  pReq->m_bufProcessed = packetLen;
1158
1424
 
1159
1425
  //OPTIMIZATION
@@ -1167,40 +1433,52 @@ static int readReq( LSAPI_Request * pReq )
1167
1433
  }
1168
1434
 
1169
1435
 
1170
-
1171
1436
  int LSAPI_Init(void)
1172
1437
  {
1173
1438
  if ( !g_inited )
1174
1439
  {
1175
1440
  s_uid = geteuid();
1176
- s_pSecret[0] = 0;
1441
+ s_secret[0] = 0;
1177
1442
  lsapi_signal(SIGPIPE, lsapi_sigpipe);
1178
1443
  lsapi_signal(SIGUSR1, lsapi_siguser1);
1179
1444
 
1180
1445
  #if defined(SIGXFSZ) && defined(SIG_IGN)
1181
1446
  signal(SIGXFSZ, SIG_IGN);
1182
1447
  #endif
1183
- /* let STDOUT function as STDERR,
1448
+ /* let STDOUT function as STDERR,
1184
1449
  just in case writing to STDOUT directly */
1185
- dup2( 2, 1 );
1450
+ dup2( 2, 1 );
1186
1451
  if ( LSAPI_InitRequest( &g_req, LSAPI_SOCK_FILENO ) == -1 )
1187
1452
  return -1;
1188
1453
  g_inited = 1;
1189
1454
  s_ppid = getppid();
1455
+ void *pthread_lib = dlopen("libpthread.so", RTLD_LAZY);
1456
+ if (pthread_lib)
1457
+ pthread_atfork_func = dlsym(pthread_lib, "pthread_atfork");
1458
+
1190
1459
  }
1191
1460
  return 0;
1192
1461
  }
1193
1462
 
1463
+
1194
1464
  void LSAPI_Stop(void)
1195
1465
  {
1196
1466
  g_running = 0;
1197
1467
  }
1198
1468
 
1469
+
1199
1470
  int LSAPI_IsRunning(void)
1200
1471
  {
1201
1472
  return g_running;
1202
1473
  }
1203
1474
 
1475
+
1476
+ void LSAPI_Register_Pgrp_Timer_Callback(LSAPI_On_Timer_pf cb)
1477
+ {
1478
+ s_proc_group_timer_cb = cb;
1479
+ }
1480
+
1481
+
1204
1482
  int LSAPI_InitRequest( LSAPI_Request * pReq, int fd )
1205
1483
  {
1206
1484
  int newfd;
@@ -1222,8 +1500,8 @@ int LSAPI_InitRequest( LSAPI_Request * pReq, int fd )
1222
1500
  {
1223
1501
  fd = dup( fd );
1224
1502
  newfd = open( "/dev/null", O_RDWR );
1225
- dup2( newfd, STDIN_FILENO );
1226
- }
1503
+ dup2( newfd, STDIN_FILENO );
1504
+ }
1227
1505
 
1228
1506
  if ( isPipe( fd ) )
1229
1507
  {
@@ -1239,24 +1517,25 @@ int LSAPI_InitRequest( LSAPI_Request * pReq, int fd )
1239
1517
  return 0;
1240
1518
  }
1241
1519
 
1520
+
1242
1521
  int LSAPI_Is_Listen( void )
1243
1522
  {
1244
1523
  return LSAPI_Is_Listen_r( &g_req );
1245
1524
  }
1246
1525
 
1526
+
1247
1527
  int LSAPI_Is_Listen_r( LSAPI_Request * pReq)
1248
1528
  {
1249
1529
  return pReq->m_fdListen != -1;
1250
1530
  }
1251
1531
 
1252
1532
 
1253
-
1254
1533
  int LSAPI_Accept_r( LSAPI_Request * pReq )
1255
1534
  {
1256
1535
  char achPeer[128];
1257
1536
  socklen_t len;
1258
1537
  int nodelay = 1;
1259
-
1538
+
1260
1539
  if ( !pReq )
1261
1540
  return -1;
1262
1541
  if ( LSAPI_Finish_r( pReq ) == -1 )
@@ -1280,9 +1559,14 @@ int LSAPI_Accept_r( LSAPI_Request * pReq )
1280
1559
  }
1281
1560
  else
1282
1561
  {
1562
+ if (s_worker_status)
1563
+ __sync_lock_test_and_set(&s_worker_status->m_state,
1564
+ LSAPI_STATE_CONNECTED);
1565
+ if (s_busy_workers)
1566
+ __sync_fetch_and_add(s_busy_workers, 1);
1283
1567
  lsapi_set_nblock( pReq->m_fd , 0 );
1284
1568
  if (((struct sockaddr *)&achPeer)->sa_family == AF_INET )
1285
- {
1569
+ {
1286
1570
  setsockopt(pReq->m_fd, IPPROTO_TCP, TCP_NODELAY,
1287
1571
  (char *)&nodelay, sizeof(nodelay));
1288
1572
  }
@@ -1299,15 +1583,19 @@ int LSAPI_Accept_r( LSAPI_Request * pReq )
1299
1583
  if ( !readReq( pReq ) )
1300
1584
  break;
1301
1585
  //abort();
1302
- lsapi_close( pReq->m_fd );
1303
- pReq->m_fd = -1;
1586
+ lsapi_close_connection(pReq);
1304
1587
  LSAPI_Reset_r( pReq );
1305
1588
  }
1306
1589
  return 0;
1307
1590
  }
1308
1591
 
1309
- static struct lsapi_packet_header finish = {'L', 'S',
1310
- LSAPI_RESP_END, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} };
1592
+
1593
+ static struct lsapi_packet_header finish_close[2] =
1594
+ {
1595
+ {'L', 'S', LSAPI_RESP_END, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} },
1596
+ {'L', 'S', LSAPI_CONN_CLOSE, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} }
1597
+ };
1598
+
1311
1599
 
1312
1600
  int LSAPI_Finish_r( LSAPI_Request * pReq )
1313
1601
  {
@@ -1326,8 +1614,8 @@ int LSAPI_Finish_r( LSAPI_Request * pReq )
1326
1614
  {
1327
1615
  Flush_RespBuf_r( pReq );
1328
1616
  }
1329
-
1330
- pReq->m_pIovecCur->iov_base = (void *)&finish;
1617
+
1618
+ pReq->m_pIovecCur->iov_base = (void *)finish_close;
1331
1619
  pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN;
1332
1620
  pReq->m_totalLen += LSAPI_PACKET_HEADER_LEN;
1333
1621
  ++pReq->m_pIovecCur;
@@ -1339,12 +1627,47 @@ int LSAPI_Finish_r( LSAPI_Request * pReq )
1339
1627
  }
1340
1628
 
1341
1629
 
1630
+ int LSAPI_End_Response_r(LSAPI_Request * pReq)
1631
+ {
1632
+ if (!pReq)
1633
+ return -1;
1634
+ if (pReq->m_reqState & LSAPI_ST_BACKGROUND)
1635
+ return 0;
1636
+ if (pReq->m_reqState)
1637
+ {
1638
+ if ( pReq->m_fd != -1 )
1639
+ {
1640
+ if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER )
1641
+ {
1642
+ if ( pReq->m_pRespHeaderBufPos <= pReq->m_pRespHeaderBuf )
1643
+ return 0;
1644
+
1645
+ LSAPI_FinalizeRespHeaders_r( pReq );
1646
+ }
1647
+ if ( pReq->m_pRespBufPos != pReq->m_pRespBuf )
1648
+ {
1649
+ Flush_RespBuf_r( pReq );
1650
+ }
1651
+
1652
+ pReq->m_pIovecCur->iov_base = (void *)finish_close;
1653
+ pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN << 1;
1654
+ pReq->m_totalLen += LSAPI_PACKET_HEADER_LEN << 1;
1655
+ ++pReq->m_pIovecCur;
1656
+ LSAPI_Flush_r( pReq );
1657
+ lsapi_close_connection(pReq);
1658
+ }
1659
+ pReq->m_reqState |= LSAPI_ST_BACKGROUND;
1660
+ }
1661
+ return 0;
1662
+ }
1663
+
1664
+
1342
1665
  void LSAPI_Reset_r( LSAPI_Request * pReq )
1343
1666
  {
1344
1667
  pReq->m_pRespBufPos = pReq->m_pRespBuf;
1345
1668
  pReq->m_pIovecCur = pReq->m_pIovecToWrite = pReq->m_pIovec + 1;
1346
1669
  pReq->m_pRespHeaderBufPos = pReq->m_pRespHeaderBuf;
1347
-
1670
+
1348
1671
  memset( &pReq->m_pHeaderIndex, 0,
1349
1672
  (char *)(pReq->m_respHeaderLen) - (char *)&pReq->m_pHeaderIndex );
1350
1673
  }
@@ -1359,7 +1682,7 @@ int LSAPI_Release_r( LSAPI_Request * pReq )
1359
1682
  if ( pReq->m_pEnvList )
1360
1683
  free( pReq->m_pEnvList );
1361
1684
  if ( pReq->m_pRespHeaderBuf )
1362
- free( pReq->m_pRespHeaderBuf );
1685
+ free( pReq->m_pRespHeaderBuf );
1363
1686
  return 0;
1364
1687
  }
1365
1688
 
@@ -1381,6 +1704,7 @@ char * LSAPI_GetHeader_r( LSAPI_Request * pReq, int headerIndex )
1381
1704
  return pReq->m_pHttpHeader + off;
1382
1705
  }
1383
1706
 
1707
+
1384
1708
  static int readBodyToReqBuf( LSAPI_Request * pReq )
1385
1709
  {
1386
1710
  off_t bodyLeft;
@@ -1395,7 +1719,7 @@ static int readBodyToReqBuf( LSAPI_Request * pReq )
1395
1719
  return -1;
1396
1720
  if ( len > bodyLeft )
1397
1721
  len = bodyLeft;
1398
-
1722
+
1399
1723
  len = lsapi_read( pReq->m_fd, pReq->m_pReqBuf + pReq->m_bufRead, len );
1400
1724
  if ( len > 0 )
1401
1725
  pReq->m_bufRead += len;
@@ -1417,7 +1741,6 @@ int LSAPI_ReqBodyGetChar_r( LSAPI_Request * pReq )
1417
1741
  }
1418
1742
 
1419
1743
 
1420
-
1421
1744
  int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen, int *getLF )
1422
1745
  {
1423
1746
  ssize_t len;
@@ -1426,12 +1749,12 @@ int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen, in
1426
1749
  char * pBufCur = pBuf;
1427
1750
  char * pCur;
1428
1751
  char * p;
1429
- if (!pReq || (pReq->m_fd ==-1) ||( !pBuf )||(bufLen < 0 )|| !getLF )
1752
+ if (!pReq || pReq->m_fd == -1 || !pBuf || !getLF)
1430
1753
  return -1;
1431
1754
  *getLF = 0;
1432
1755
  while( (left = pBufEnd - pBufCur ) > 0 )
1433
1756
  {
1434
-
1757
+
1435
1758
  len = pReq->m_bufRead - pReq->m_bufProcessed;
1436
1759
  if ( len <= 0 )
1437
1760
  {
@@ -1452,7 +1775,7 @@ int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen, in
1452
1775
  pReq->m_bufProcessed += len;
1453
1776
 
1454
1777
  pReq->m_reqBodyRead += len;
1455
-
1778
+
1456
1779
  if ( p )
1457
1780
  {
1458
1781
  *getLF = 1;
@@ -1460,7 +1783,7 @@ int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen, in
1460
1783
  }
1461
1784
  }
1462
1785
  *pBufCur = 0;
1463
-
1786
+
1464
1787
  return pBufCur - pBuf;
1465
1788
  }
1466
1789
 
@@ -1470,21 +1793,21 @@ ssize_t LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen )
1470
1793
  ssize_t len;
1471
1794
  off_t total;
1472
1795
  /* char *pOldBuf = pBuf; */
1473
- if (!pReq || (pReq->m_fd ==-1) || ( !pBuf )||(bufLen < 0 ))
1796
+ if (!pReq || pReq->m_fd == -1 || !pBuf || (ssize_t)bufLen < 0)
1474
1797
  return -1;
1475
1798
 
1476
1799
  total = pReq->m_reqBodyLen - pReq->m_reqBodyRead;
1477
-
1800
+
1478
1801
  if ( total <= 0 )
1479
1802
  return 0;
1480
- if ( total < bufLen )
1803
+ if ( total < (ssize_t)bufLen )
1481
1804
  bufLen = total;
1482
1805
 
1483
1806
  total = 0;
1484
1807
  len = pReq->m_bufRead - pReq->m_bufProcessed;
1485
1808
  if ( len > 0 )
1486
1809
  {
1487
- if ( len > bufLen )
1810
+ if ( len > (ssize_t)bufLen )
1488
1811
  len = bufLen;
1489
1812
  memmove( pBuf, pReq->m_pReqBuf + pReq->m_bufProcessed, len );
1490
1813
  pReq->m_bufProcessed += len;
@@ -1510,7 +1833,7 @@ ssize_t LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen )
1510
1833
  }
1511
1834
  pReq->m_reqBodyRead += total;
1512
1835
  return total;
1513
-
1836
+
1514
1837
  }
1515
1838
 
1516
1839
 
@@ -1523,8 +1846,12 @@ ssize_t LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, size_t len )
1523
1846
  ssize_t toWrite;
1524
1847
  ssize_t packetLen;
1525
1848
  int skip = 0;
1526
-
1527
- if ( !pReq || !pBuf || (pReq->m_fd == -1) )
1849
+
1850
+ if (!pReq || !pBuf)
1851
+ return -1;
1852
+ if (pReq->m_reqState & LSAPI_ST_BACKGROUND)
1853
+ return len;
1854
+ if (pReq->m_fd == -1)
1528
1855
  return -1;
1529
1856
  if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER )
1530
1857
  {
@@ -1542,19 +1869,19 @@ ssize_t LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, size_t len )
1542
1869
  }
1543
1870
  pReq->m_reqState |= LSAPI_ST_RESP_BODY;
1544
1871
 
1545
- if ( (len - skip) < pReq->m_pRespBufEnd - pReq->m_pRespBufPos )
1872
+ if ( ((ssize_t)len - skip) < pReq->m_pRespBufEnd - pReq->m_pRespBufPos )
1546
1873
  {
1547
1874
  memmove( pReq->m_pRespBufPos, pBuf + skip, len - skip );
1548
1875
  pReq->m_pRespBufPos += len - skip;
1549
1876
  return len;
1550
1877
  }
1551
-
1552
-
1878
+
1879
+
1553
1880
  pHeader = pReq->m_respPktHeader;
1554
1881
  p = pBuf + skip;
1555
1882
  pEnd = pBuf + len;
1556
1883
  bufLen = pReq->m_pRespBufPos - pReq->m_pRespBuf;
1557
-
1884
+
1558
1885
  while( ( toWrite = pEnd - p ) > 0 )
1559
1886
  {
1560
1887
  packetLen = toWrite + bufLen;
@@ -1563,7 +1890,7 @@ ssize_t LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, size_t len )
1563
1890
  packetLen = LSAPI_MAX_DATA_PACKET_LEN;
1564
1891
  toWrite = packetLen - bufLen;
1565
1892
  }
1566
-
1893
+
1567
1894
  lsapi_buildPacketHeader( pHeader, LSAPI_RESP_STREAM,
1568
1895
  packetLen + LSAPI_PACKET_HEADER_LEN );
1569
1896
  pReq->m_totalLen += packetLen + LSAPI_PACKET_HEADER_LEN;
@@ -1577,7 +1904,7 @@ ssize_t LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, size_t len )
1577
1904
  pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespBuf;
1578
1905
  pReq->m_pIovecCur->iov_len = bufLen;
1579
1906
  pReq->m_pRespBufPos = pReq->m_pRespBuf;
1580
- ++pReq->m_pIovecCur;
1907
+ ++pReq->m_pIovecCur;
1581
1908
  bufLen = 0;
1582
1909
  }
1583
1910
 
@@ -1599,7 +1926,8 @@ ssize_t LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, size_t len )
1599
1926
  return p - pBuf;
1600
1927
  }
1601
1928
 
1602
- #if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__)
1929
+
1930
+ #if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__)
1603
1931
  ssize_t gsendfile( int fdOut, int fdIn, off_t* off, size_t size )
1604
1932
  {
1605
1933
  ssize_t ret;
@@ -1614,6 +1942,7 @@ ssize_t gsendfile( int fdOut, int fdIn, off_t* off, size_t size )
1614
1942
  }
1615
1943
  #endif
1616
1944
 
1945
+
1617
1946
  #if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
1618
1947
  ssize_t gsendfile( int fdOut, int fdIn, off_t* off, size_t size )
1619
1948
  {
@@ -1628,7 +1957,8 @@ ssize_t gsendfile( int fdOut, int fdIn, off_t* off, size_t size )
1628
1957
  return ret;
1629
1958
  }
1630
1959
  #endif
1631
-
1960
+
1961
+
1632
1962
  #if defined(sun) || defined(__sun)
1633
1963
  #include <sys/sendfile.h>
1634
1964
  ssize_t gsendfile( int fdOut, int fdIn, off_t *off, size_t size )
@@ -1652,11 +1982,14 @@ ssize_t gsendfile( int fdOut, int fdIn, off_t *off, size_t size )
1652
1982
  }
1653
1983
  #endif
1654
1984
 
1985
+
1655
1986
  #if defined(linux) || defined(__linux) || defined(__linux__) || \
1656
1987
  defined(__gnu_linux__)
1657
1988
  #include <sys/sendfile.h>
1658
1989
  #define gsendfile sendfile
1659
1990
  #endif
1991
+
1992
+
1660
1993
  #if defined(HPUX)
1661
1994
  ssize_t gsendfile( int fdOut, int fdIn, off_t * off, size_t size )
1662
1995
  {
@@ -1664,6 +1997,7 @@ ssize_t gsendfile( int fdOut, int fdIn, off_t * off, size_t size )
1664
1997
  }
1665
1998
  #endif
1666
1999
 
2000
+
1667
2001
  ssize_t LSAPI_sendfile_r( LSAPI_Request * pReq, int fdIn, off_t* off, size_t size )
1668
2002
  {
1669
2003
  struct lsapi_packet_header * pHeader = pReq->m_respPktHeader;
@@ -1674,16 +2008,16 @@ ssize_t LSAPI_sendfile_r( LSAPI_Request * pReq, int fdIn, off_t* off, size_t siz
1674
2008
  LSAPI_FinalizeRespHeaders_r( pReq );
1675
2009
  }
1676
2010
  pReq->m_reqState |= LSAPI_ST_RESP_BODY;
1677
-
2011
+
1678
2012
  LSAPI_Flush_r(pReq);
1679
-
2013
+
1680
2014
  lsapi_buildPacketHeader( pHeader, LSAPI_RESP_STREAM,
1681
2015
  size + LSAPI_PACKET_HEADER_LEN );
1682
-
2016
+
1683
2017
 
1684
2018
  if (write(pReq->m_fd, (const char *) pHeader, LSAPI_PACKET_HEADER_LEN ) != LSAPI_PACKET_HEADER_LEN)
1685
2019
  return -1;
1686
-
2020
+
1687
2021
  return gsendfile( pReq->m_fd, fdIn, off, size );
1688
2022
  }
1689
2023
 
@@ -1706,14 +2040,12 @@ void Flush_RespBuf_r( LSAPI_Request * pReq )
1706
2040
  pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespBuf;
1707
2041
  pReq->m_pIovecCur->iov_len = bufLen;
1708
2042
  pReq->m_pRespBufPos = pReq->m_pRespBuf;
1709
- ++pReq->m_pIovecCur;
2043
+ ++pReq->m_pIovecCur;
1710
2044
  bufLen = 0;
1711
2045
  }
1712
2046
  }
1713
2047
 
1714
2048
 
1715
-
1716
-
1717
2049
  int LSAPI_Flush_r( LSAPI_Request * pReq )
1718
2050
  {
1719
2051
  int ret = 0;
@@ -1738,17 +2070,16 @@ int LSAPI_Flush_r( LSAPI_Request * pReq )
1738
2070
  {
1739
2071
  Flush_RespBuf_r( pReq );
1740
2072
  }
1741
-
2073
+
1742
2074
  n = pReq->m_pIovecCur - pReq->m_pIovecToWrite;
1743
2075
  if ( n > 0 )
1744
2076
  {
1745
-
2077
+
1746
2078
  ret = lsapi_writev( pReq->m_fd, &pReq->m_pIovecToWrite,
1747
2079
  n, pReq->m_totalLen );
1748
2080
  if ( ret < pReq->m_totalLen )
1749
2081
  {
1750
- lsapi_close( pReq->m_fd );
1751
- pReq->m_fd = -1;
2082
+ lsapi_close_connection(pReq);
1752
2083
  ret = -1;
1753
2084
  }
1754
2085
  pReq->m_totalLen = 0;
@@ -1768,16 +2099,16 @@ ssize_t LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, size_t le
1768
2099
  int ret;
1769
2100
  struct iovec iov[2];
1770
2101
  struct iovec *pIov;
1771
-
2102
+
1772
2103
  if ( !pReq )
1773
2104
  return -1;
1774
- if (( pReq->m_fd == -1 )||(pReq->m_fd == pReq->m_fdListen ))
2105
+ if (s_stderr_log_path || pReq->m_fd == -1 || pReq->m_fd == pReq->m_fdListen)
1775
2106
  return write( 2, pBuf, len );
1776
2107
  if ( pReq->m_pRespBufPos != pReq->m_pRespBuf )
1777
2108
  {
1778
2109
  LSAPI_Flush_r( pReq );
1779
2110
  }
1780
-
2111
+
1781
2112
  p = pBuf;
1782
2113
  pEnd = pBuf + len;
1783
2114
 
@@ -1803,14 +2134,14 @@ ssize_t LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, size_t le
1803
2134
  2, totalLen );
1804
2135
  if ( ret < totalLen )
1805
2136
  {
1806
- lsapi_close( pReq->m_fd );
1807
- pReq->m_fd = -1;
2137
+ lsapi_close_connection(pReq);
1808
2138
  ret = -1;
1809
2139
  }
1810
2140
  }
1811
2141
  return p - pBuf;
1812
2142
  }
1813
2143
 
2144
+
1814
2145
  static char * GetHeaderVar( LSAPI_Request * pReq, const char * name )
1815
2146
  {
1816
2147
  int i;
@@ -1890,6 +2221,7 @@ char * LSAPI_GetEnv_r( LSAPI_Request * pReq, const char * name )
1890
2221
  return NULL;
1891
2222
  }
1892
2223
 
2224
+
1893
2225
  struct _headerInfo
1894
2226
  {
1895
2227
  const char * _name;
@@ -1898,12 +2230,14 @@ struct _headerInfo
1898
2230
  int _valueLen;
1899
2231
  };
1900
2232
 
2233
+
1901
2234
  int compareValueLocation(const void * v1, const void *v2 )
1902
2235
  {
1903
2236
  return ((const struct _headerInfo *)v1)->_value -
1904
- ((const struct _headerInfo *)v2)->_value;
2237
+ ((const struct _headerInfo *)v2)->_value;
1905
2238
  }
1906
2239
 
2240
+
1907
2241
  int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq,
1908
2242
  LSAPI_CB_EnvHandler fn, void * arg )
1909
2243
  {
@@ -1932,7 +2266,7 @@ int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq,
1932
2266
  headers[count]._value = pValue;
1933
2267
  headers[count]._valueLen = len;
1934
2268
  ++count;
1935
-
2269
+
1936
2270
  //ret = (*fn)( HTTP_HEADERS[i], HTTP_HEADER_LEN[i],
1937
2271
  // pValue, len, arg );
1938
2272
  //if ( ret <= 0 )
@@ -1961,7 +2295,7 @@ int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq,
1961
2295
  ++count;
1962
2296
  if ( count == 512 )
1963
2297
  break;
1964
- //ret = (*fn)( pKey, keyLen,
2298
+ //ret = (*fn)( pKey, keyLen,
1965
2299
  // pValue, pCur->valueLen, arg );
1966
2300
  //if ( ret <= 0 )
1967
2301
  // return ret;
@@ -1971,13 +2305,12 @@ int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq,
1971
2305
  qsort( headers, count, sizeof( struct _headerInfo ), compareValueLocation );
1972
2306
  for( i = 0; i < count; ++i )
1973
2307
  {
1974
- ret = (*fn)( headers[i]._name, headers[i]._nameLen,
2308
+ ret = (*fn)( headers[i]._name, headers[i]._nameLen,
1975
2309
  headers[i]._value, headers[i]._valueLen, arg );
1976
2310
  if ( ret <= 0 )
1977
2311
  return ret;
1978
2312
  }
1979
2313
  return count;
1980
-
1981
2314
  }
1982
2315
 
1983
2316
 
@@ -2038,7 +2371,7 @@ int LSAPI_ForeachHeader_r( LSAPI_Request * pReq,
2038
2371
 
2039
2372
  pValue = pReq->m_pHttpHeader + pCur->valueOff;
2040
2373
  *(pValue + pCur->valueLen ) = 0;
2041
- ret = (*fn)( achHeaderName, keyLen,
2374
+ ret = (*fn)( achHeaderName, keyLen,
2042
2375
  pValue, pCur->valueLen, arg );
2043
2376
  if ( ret <= 0 )
2044
2377
  return ret;
@@ -2046,9 +2379,9 @@ int LSAPI_ForeachHeader_r( LSAPI_Request * pReq,
2046
2379
  }
2047
2380
  }
2048
2381
  return count + pReq->m_pHeader->m_cntUnknownHeaders;
2049
-
2050
2382
  }
2051
2383
 
2384
+
2052
2385
  static int EnvForeach( struct LSAPI_key_value_pair * pEnv,
2053
2386
  int n, LSAPI_CB_EnvHandler fn, void * arg )
2054
2387
  {
@@ -2068,7 +2401,6 @@ static int EnvForeach( struct LSAPI_key_value_pair * pEnv,
2068
2401
  }
2069
2402
 
2070
2403
 
2071
-
2072
2404
  int LSAPI_ForeachEnv_r( LSAPI_Request * pReq,
2073
2405
  LSAPI_CB_EnvHandler fn, void * arg )
2074
2406
  {
@@ -2083,7 +2415,6 @@ int LSAPI_ForeachEnv_r( LSAPI_Request * pReq,
2083
2415
  }
2084
2416
 
2085
2417
 
2086
-
2087
2418
  int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq,
2088
2419
  LSAPI_CB_EnvHandler fn, void * arg )
2089
2420
  {
@@ -2100,7 +2431,6 @@ int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq,
2100
2431
  }
2101
2432
 
2102
2433
 
2103
-
2104
2434
  int LSAPI_FinalizeRespHeaders_r( LSAPI_Request * pReq )
2105
2435
  {
2106
2436
  if ( !pReq || !pReq->m_pIovec )
@@ -2115,7 +2445,7 @@ int LSAPI_FinalizeRespHeaders_r( LSAPI_Request * pReq )
2115
2445
  pReq->m_totalLen += pReq->m_pIovecCur->iov_len;
2116
2446
  ++pReq->m_pIovecCur;
2117
2447
  }
2118
-
2448
+
2119
2449
  pReq->m_pIovec->iov_len = sizeof( struct lsapi_resp_header)
2120
2450
  + pReq->m_respHeader.m_respInfo.m_cntHeaders * sizeof( short );
2121
2451
  pReq->m_totalLen += pReq->m_pIovec->iov_len;
@@ -2128,11 +2458,11 @@ int LSAPI_FinalizeRespHeaders_r( LSAPI_Request * pReq )
2128
2458
  }
2129
2459
 
2130
2460
 
2131
- int LSAPI_AppendRespHeader2_r( LSAPI_Request * pReq, const char * pHeaderName,
2461
+ int LSAPI_AppendRespHeader2_r( LSAPI_Request * pReq, const char * pHeaderName,
2132
2462
  const char * pHeaderValue )
2133
2463
  {
2134
2464
  int nameLen, valLen, len;
2135
- if ( !pReq || !pHeaderName || !pHeaderValue )
2465
+ if ( !pReq || !pHeaderName || !pHeaderValue )
2136
2466
  return -1;
2137
2467
  if ( pReq->m_reqState & LSAPI_ST_RESP_BODY )
2138
2468
  return -1;
@@ -2184,7 +2514,6 @@ int LSAPI_AppendRespHeader2_r( LSAPI_Request * pReq, const char * pHeaderName,
2184
2514
  }
2185
2515
 
2186
2516
 
2187
-
2188
2517
  int LSAPI_AppendRespHeader_r( LSAPI_Request * pReq, const char * pBuf, int len )
2189
2518
  {
2190
2519
  if ( !pReq || !pBuf || len <= 0 || len > LSAPI_RESP_HTTP_HEADER_MAX )
@@ -2265,9 +2594,9 @@ int LSAPI_CreateListenSock2( const struct sockaddr * pServerAddr, int backlog )
2265
2594
  close(fd);
2266
2595
  errno = ret;
2267
2596
  return -1;
2268
-
2269
2597
  }
2270
2598
 
2599
+
2271
2600
  int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr )
2272
2601
  {
2273
2602
  char achAddr[256];
@@ -2276,14 +2605,15 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr )
2276
2605
  struct addrinfo *res, hints;
2277
2606
  int doAddrInfo = 0;
2278
2607
  int port;
2279
-
2608
+
2280
2609
  if ( !pBind )
2281
2610
  return -1;
2282
2611
 
2283
2612
  while( isspace( *pBind ) )
2284
2613
  ++pBind;
2285
2614
 
2286
- strncpy( achAddr, pBind, 256 );
2615
+ strncpy(achAddr, pBind, 255);
2616
+ achAddr[255] = 0;
2287
2617
 
2288
2618
  switch( *p )
2289
2619
  {
@@ -2300,7 +2630,7 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr )
2300
2630
  if ( !pEnd )
2301
2631
  return -1;
2302
2632
  *pEnd++ = 0;
2303
-
2633
+
2304
2634
  if ( *p == '*' )
2305
2635
  {
2306
2636
  strcpy( achAddr, "::" );
@@ -2315,7 +2645,7 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr )
2315
2645
  if ( !pEnd )
2316
2646
  return -1;
2317
2647
  *pEnd++ = 0;
2318
-
2648
+
2319
2649
  doAddrInfo = 0;
2320
2650
  if ( *p == '*' )
2321
2651
  {
@@ -2335,7 +2665,7 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr )
2335
2665
  }
2336
2666
  if ( *pEnd == ':' )
2337
2667
  ++pEnd;
2338
-
2668
+
2339
2669
  port = atoi( pEnd );
2340
2670
  if (( port <= 0 )||( port > 65535 ))
2341
2671
  return -1;
@@ -2356,15 +2686,16 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr )
2356
2686
  memcpy(pAddr, res->ai_addr, res->ai_addrlen);
2357
2687
  freeaddrinfo(res);
2358
2688
  }
2359
-
2689
+
2360
2690
  if ( pAddr->sa_family == AF_INET )
2361
2691
  ((struct sockaddr_in *)pAddr)->sin_port = htons( port );
2362
2692
  else
2363
2693
  ((struct sockaddr_in6 *)pAddr)->sin6_port = htons( port );
2364
2694
  return 0;
2365
-
2695
+
2366
2696
  }
2367
2697
 
2698
+
2368
2699
  int LSAPI_CreateListenSock( const char * pBind, int backlog )
2369
2700
  {
2370
2701
  char serverAddr[128];
@@ -2378,25 +2709,8 @@ int LSAPI_CreateListenSock( const char * pBind, int backlog )
2378
2709
  return fd;
2379
2710
  }
2380
2711
 
2381
- static fn_select_t g_fnSelect = select;
2382
-
2383
- typedef struct _lsapi_child_status
2384
- {
2385
- int m_pid;
2386
- long m_tmStart;
2387
-
2388
- volatile short m_iKillSent;
2389
- volatile short m_inProcess;
2390
- volatile int m_iReqCounter;
2391
-
2392
- volatile long m_tmWaitBegin;
2393
- volatile long m_tmReqBegin;
2394
- volatile long m_tmLastCheckPoint;
2395
- }
2396
- lsapi_child_status;
2397
-
2398
- static lsapi_child_status * s_pChildStatus = NULL;
2399
2712
 
2713
+ static fn_select_t g_fnSelect = select;
2400
2714
  typedef struct _lsapi_prefork_server
2401
2715
  {
2402
2716
  int m_fd;
@@ -2408,18 +2722,17 @@ typedef struct _lsapi_prefork_server
2408
2722
  int m_iChildrenMaxIdleTime;
2409
2723
  int m_iMaxReqProcessTime;
2410
2724
  int m_iAvoidFork;
2411
-
2725
+
2412
2726
  lsapi_child_status * m_pChildrenStatus;
2413
2727
  lsapi_child_status * m_pChildrenStatusCur;
2414
2728
  lsapi_child_status * m_pChildrenStatusEnd;
2415
-
2416
- }lsapi_prefork_server;
2417
2729
 
2730
+ }lsapi_prefork_server;
2418
2731
  static lsapi_prefork_server * g_prefork_server = NULL;
2419
2732
 
2733
+
2420
2734
  int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork )
2421
2735
  {
2422
- int pid;
2423
2736
  if ( g_prefork_server )
2424
2737
  return 0;
2425
2738
  if ( max_children <= 1 )
@@ -2427,7 +2740,9 @@ int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork )
2427
2740
  if ( max_children >= 10000)
2428
2741
  max_children = 10000;
2429
2742
 
2430
-
2743
+ if (s_max_busy_workers == 0)
2744
+ s_max_busy_workers = max_children / 2 + 1;
2745
+
2431
2746
  g_prefork_server = (lsapi_prefork_server *)malloc( sizeof( lsapi_prefork_server ) );
2432
2747
  if ( !g_prefork_server )
2433
2748
  return -1;
@@ -2437,20 +2752,27 @@ int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork )
2437
2752
  g_fnSelect = fp;
2438
2753
 
2439
2754
  s_ppid = getppid();
2440
- pid = getpid();
2441
- setpgid( pid, pid );
2755
+ s_pid = getpid();
2756
+ setpgid( s_pid, s_pid );
2757
+ #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
2758
+ s_total_pages = sysconf(_SC_PHYS_PAGES);
2759
+ #endif
2442
2760
  g_prefork_server->m_iAvoidFork = avoidFork;
2443
2761
  g_prefork_server->m_iMaxChildren = max_children;
2444
-
2762
+
2445
2763
  g_prefork_server->m_iExtraChildren = ( avoidFork ) ? 0 : (max_children / 3) ;
2446
2764
  g_prefork_server->m_iMaxIdleChildren = ( avoidFork ) ? (max_children + 1) : (max_children / 3);
2447
2765
  if ( g_prefork_server->m_iMaxIdleChildren == 0 )
2448
2766
  g_prefork_server->m_iMaxIdleChildren = 1;
2449
2767
  g_prefork_server->m_iChildrenMaxIdleTime = 300;
2450
2768
  g_prefork_server->m_iMaxReqProcessTime = 3600;
2451
- return 0;
2769
+
2770
+ setsid();
2771
+
2772
+ return 0;
2452
2773
  }
2453
2774
 
2775
+
2454
2776
  void LSAPI_Set_Server_fd( int fd )
2455
2777
  {
2456
2778
  if( g_prefork_server )
@@ -2484,12 +2806,8 @@ static int lsapi_accept( int fdListen )
2484
2806
  }
2485
2807
 
2486
2808
 
2487
-
2488
-
2489
- static int s_req_processed = 0;
2490
- static int s_max_reqs = 10000;
2809
+ static unsigned int s_max_reqs = UINT_MAX;
2491
2810
  static int s_max_idle_secs = 300;
2492
-
2493
2811
  static int s_stop;
2494
2812
 
2495
2813
  static void lsapi_cleanup(int signal)
@@ -2497,6 +2815,7 @@ static void lsapi_cleanup(int signal)
2497
2815
  s_stop = signal;
2498
2816
  }
2499
2817
 
2818
+
2500
2819
  static lsapi_child_status * find_child_status( int pid )
2501
2820
  {
2502
2821
  lsapi_child_status * pStatus = g_prefork_server->m_pChildrenStatus;
@@ -2505,6 +2824,11 @@ static lsapi_child_status * find_child_status( int pid )
2505
2824
  {
2506
2825
  if ( pStatus->m_pid == pid )
2507
2826
  {
2827
+ if (pid == 0)
2828
+ {
2829
+ memset(pStatus, 0, sizeof( *pStatus ) );
2830
+ pStatus->m_pid = -1;
2831
+ }
2508
2832
  if ( pStatus + 1 > g_prefork_server->m_pChildrenStatusCur )
2509
2833
  g_prefork_server->m_pChildrenStatusCur = pStatus + 1;
2510
2834
  return pStatus;
@@ -2515,11 +2839,33 @@ static lsapi_child_status * find_child_status( int pid )
2515
2839
  }
2516
2840
 
2517
2841
 
2842
+ void LSAPI_reset_server_state( void )
2843
+ {
2844
+ /*
2845
+ Reset child status
2846
+ */
2847
+ g_prefork_server->m_iCurChildren = 0;
2848
+ lsapi_child_status * pStatus = g_prefork_server->m_pChildrenStatus;
2849
+ lsapi_child_status * pEnd = g_prefork_server->m_pChildrenStatusEnd;
2850
+ while( pStatus < pEnd )
2851
+ {
2852
+ pStatus->m_pid = 0;
2853
+ ++pStatus;
2854
+ }
2855
+ if (s_busy_workers)
2856
+ __sync_lock_release(s_busy_workers);
2857
+ if (s_accepting_workers)
2858
+ __sync_lock_release(s_accepting_workers);
2859
+
2860
+ }
2861
+
2518
2862
 
2519
2863
  static void lsapi_sigchild( int signal )
2520
2864
  {
2521
2865
  int status, pid;
2522
2866
  lsapi_child_status * child_status;
2867
+ if (g_prefork_server == NULL)
2868
+ return;
2523
2869
  while( 1 )
2524
2870
  {
2525
2871
  pid = waitpid( -1, &status, WNOHANG|WUNTRACED );
@@ -2531,19 +2877,39 @@ static void lsapi_sigchild( int signal )
2531
2877
  {
2532
2878
  int sig_num = WTERMSIG( status );
2533
2879
  int dump = WCOREDUMP( status );
2534
- fprintf( stderr, "Child process with pid: %d was killed by signal: %d, core dump: %d\n", pid, sig_num, dump );
2880
+ lsapi_log("Child process with pid: %d was killed by signal: "
2881
+ "%d, core dump: %d\n", pid, sig_num, dump );
2535
2882
  }
2536
2883
  if ( pid == s_pid_dump_debug_info )
2537
2884
  {
2538
2885
  pid = 0;
2539
2886
  continue;
2540
2887
  }
2888
+ if ( pid == s_ignore_pid )
2889
+ {
2890
+ pid = 0;
2891
+ s_ignore_pid = -1;
2892
+ continue;
2893
+ }
2541
2894
  child_status = find_child_status( pid );
2542
2895
  if ( child_status )
2543
2896
  {
2897
+ if (__sync_bool_compare_and_swap(&child_status->m_state,
2898
+ LSAPI_STATE_CONNECTED,
2899
+ LSAPI_STATE_IDLE))
2900
+ {
2901
+ if (s_busy_workers)
2902
+ __sync_fetch_and_sub(s_busy_workers, 1);
2903
+ }
2904
+ else if (__sync_bool_compare_and_swap(&child_status->m_state,
2905
+ LSAPI_STATE_ACCEPTING,
2906
+ LSAPI_STATE_IDLE))
2907
+ {
2908
+ if (s_accepting_workers)
2909
+ __sync_fetch_and_sub(s_accepting_workers, 1);
2910
+ }
2544
2911
  child_status->m_pid = 0;
2545
2912
  --g_prefork_server->m_iCurChildren;
2546
-
2547
2913
  }
2548
2914
  }
2549
2915
  while(( g_prefork_server->m_pChildrenStatusCur > g_prefork_server->m_pChildrenStatus )
@@ -2552,13 +2918,19 @@ static void lsapi_sigchild( int signal )
2552
2918
 
2553
2919
  }
2554
2920
 
2555
- static int lsapi_init_children_status()
2921
+
2922
+ static int lsapi_init_children_status(void)
2556
2923
  {
2924
+ char * pBuf;
2557
2925
  int size = 4096;
2926
+ int max_children;
2927
+ if (g_prefork_server->m_pChildrenStatus)
2928
+ return 0;
2929
+ max_children = g_prefork_server->m_iMaxChildren
2930
+ + g_prefork_server->m_iExtraChildren;
2558
2931
 
2559
- char * pBuf;
2560
- size = (g_prefork_server->m_iMaxChildren + g_prefork_server->m_iExtraChildren ) * sizeof( lsapi_child_status ) * 2;
2561
- size = (size + 4095 ) / 4096 * 4096;
2932
+ size = max_children * sizeof( lsapi_child_status ) * 2 + 3 * sizeof(int);
2933
+ size = (size + 4095) / 4096 * 4096;
2562
2934
  pBuf =( char*) mmap( NULL, size, PROT_READ | PROT_WRITE,
2563
2935
  MAP_ANON | MAP_SHARED, -1, 0 );
2564
2936
  if ( pBuf == MAP_FAILED )
@@ -2569,10 +2941,17 @@ static int lsapi_init_children_status()
2569
2941
  memset( pBuf, 0, size );
2570
2942
  g_prefork_server->m_pChildrenStatus = (lsapi_child_status *)pBuf;
2571
2943
  g_prefork_server->m_pChildrenStatusCur = (lsapi_child_status *)pBuf;
2572
- g_prefork_server->m_pChildrenStatusEnd = (lsapi_child_status *)pBuf + size / sizeof( lsapi_child_status );
2944
+ g_prefork_server->m_pChildrenStatusEnd = (lsapi_child_status *)pBuf + max_children;
2945
+ s_busy_workers = (int *)g_prefork_server->m_pChildrenStatusEnd;
2946
+ s_accepting_workers = s_busy_workers + 1;
2947
+ s_global_counter = s_accepting_workers + 1;
2948
+ s_avail_pages = (size_t *)(s_global_counter + 1);
2949
+
2950
+ setsid();
2573
2951
  return 0;
2574
2952
  }
2575
2953
 
2954
+
2576
2955
  static void dump_debug_info( lsapi_child_status * pStatus, long tmCur )
2577
2956
  {
2578
2957
  char achCmd[1024];
@@ -2581,17 +2960,26 @@ static void dump_debug_info( lsapi_child_status * pStatus, long tmCur )
2581
2960
  if ( kill( s_pid_dump_debug_info, 0 ) == 0 )
2582
2961
  return;
2583
2962
  }
2584
- s_pid_dump_debug_info = fork();
2585
2963
 
2586
- fprintf( stderr, "[%s] Possible runaway process, PPID: %d, PID: %d, reqCount: %d, process time: %ld, checkpoint time: %ld, start time: %ld\n",
2587
- ctime(&tmCur), getpid(), pStatus->m_pid, pStatus->m_iReqCounter,
2588
- tmCur - pStatus->m_tmReqBegin, tmCur - pStatus->m_tmLastCheckPoint, tmCur - pStatus->m_tmStart );
2589
- snprintf( achCmd, 1024, "gdb --batch -ex \"attach %d\" -ex \"set height 0\" -ex \"bt\" >&2;PATH=$PATH:/usr/sbin lsof -p %d >&2", pStatus->m_pid, pStatus->m_pid );
2590
- if ( system( achCmd ) == -1 )
2591
- perror( "system()" );
2592
- exit( 0 );
2964
+ lsapi_log("Possible runaway process, UID: %d, PPID: %d, PID: %d, "
2965
+ "reqCount: %d, process time: %ld, checkpoint time: %ld, start "
2966
+ "time: %ld\n", getuid(), getppid(), pStatus->m_pid,
2967
+ pStatus->m_iReqCounter, tmCur - pStatus->m_tmReqBegin,
2968
+ tmCur - pStatus->m_tmLastCheckPoint, tmCur - pStatus->m_tmStart );
2969
+
2970
+ s_pid_dump_debug_info = fork();
2971
+ if (s_pid_dump_debug_info == 0)
2972
+ {
2973
+ snprintf( achCmd, 1024, "gdb --batch -ex \"attach %d\" -ex \"set height 0\" "
2974
+ "-ex \"bt\" >&2;PATH=$PATH:/usr/sbin lsof -p %d >&2",
2975
+ pStatus->m_pid, pStatus->m_pid );
2976
+ if ( system( achCmd ) == -1 )
2977
+ perror( "system()" );
2978
+ exit( 0 );
2979
+ }
2593
2980
  }
2594
2981
 
2982
+
2595
2983
  static void lsapi_check_child_status( long tmCur )
2596
2984
  {
2597
2985
  int idle = 0;
@@ -2603,21 +2991,23 @@ static void lsapi_check_child_status( long tmCur )
2603
2991
  while( pStatus < pEnd )
2604
2992
  {
2605
2993
  tobekilled = 0;
2606
- if ( pStatus->m_pid != 0 )
2994
+ if ( pStatus->m_pid != 0 && pStatus->m_pid != -1)
2607
2995
  {
2608
2996
  ++count;
2609
2997
  if ( !pStatus->m_inProcess )
2610
2998
  {
2611
-
2612
- if (( g_prefork_server->m_iCurChildren - dying > g_prefork_server->m_iMaxChildren)||
2613
- ( idle > g_prefork_server->m_iMaxIdleChildren ))
2999
+
3000
+ if (g_prefork_server->m_iCurChildren - dying
3001
+ > g_prefork_server->m_iMaxChildren
3002
+ || idle > g_prefork_server->m_iMaxIdleChildren)
2614
3003
  {
2615
3004
  ++pStatus->m_iKillSent;
2616
3005
  //tobekilled = SIGUSR1;
2617
3006
  }
2618
3007
  else
2619
3008
  {
2620
- if (( s_max_idle_secs> 0)&&(tmCur - pStatus->m_tmWaitBegin > s_max_idle_secs + 5 ))
3009
+ if (s_max_idle_secs> 0
3010
+ && tmCur - pStatus->m_tmWaitBegin > s_max_idle_secs + 5)
2621
3011
  {
2622
3012
  ++pStatus->m_iKillSent;
2623
3013
  //tobekilled = SIGUSR1;
@@ -2628,26 +3018,29 @@ static void lsapi_check_child_status( long tmCur )
2628
3018
  }
2629
3019
  else
2630
3020
  {
2631
- if ( tmCur - pStatus->m_tmReqBegin >
2632
- g_prefork_server->m_iMaxReqProcessTime )
3021
+ if (tmCur - pStatus->m_tmReqBegin >
3022
+ g_prefork_server->m_iMaxReqProcessTime)
2633
3023
  {
2634
- if (( ( pStatus->m_iKillSent % 5 ) == 0 )&&( s_dump_debug_info ))
3024
+ if ((pStatus->m_iKillSent % 5) == 0 && s_dump_debug_info)
2635
3025
  dump_debug_info( pStatus, tmCur );
2636
3026
  if ( pStatus->m_iKillSent > 5 )
2637
3027
  {
2638
3028
  tobekilled = SIGKILL;
2639
- fprintf( stderr, "Force killing runaway process PID: %d with SIGKILL\n", pStatus->m_pid );
3029
+ lsapi_log("Force killing runaway process PID: %d"
3030
+ " with SIGKILL\n", pStatus->m_pid );
2640
3031
  }
2641
3032
  else
2642
3033
  {
2643
3034
  tobekilled = SIGTERM;
2644
- fprintf( stderr, "Killing runaway process PID: %d with SIGTERM\n", pStatus->m_pid );
3035
+ lsapi_log("Killing runaway process PID: %d with "
3036
+ "SIGTERM\n", pStatus->m_pid );
2645
3037
  }
2646
3038
  }
2647
3039
  }
2648
3040
  if ( tobekilled )
2649
3041
  {
2650
- if (( kill( pStatus->m_pid, tobekilled ) == -1 )&&( errno == ESRCH ))
3042
+ if (( kill( pStatus->m_pid, tobekilled ) == -1 ) &&
3043
+ ( errno == ESRCH ))
2651
3044
  {
2652
3045
  pStatus->m_pid = 0;
2653
3046
  --count;
@@ -2663,34 +3056,50 @@ static void lsapi_check_child_status( long tmCur )
2663
3056
  }
2664
3057
  if ( abs( g_prefork_server->m_iCurChildren - count ) > 1 )
2665
3058
  {
2666
- fprintf( stderr, "Children tracking is wrong: PID: %d, Cur Childen: %d, count: %d, idle: %d, dying: %d\n", getpid(),
2667
- g_prefork_server->m_iCurChildren, count, idle, dying );
2668
-
3059
+ lsapi_log("Children tracking is wrong: Cur Children: %d,"
3060
+ " count: %d, idle: %d, dying: %d\n",
3061
+ g_prefork_server->m_iCurChildren, count, idle, dying );
2669
3062
  }
2670
3063
  }
2671
3064
 
2672
- static int lsapi_all_children_must_die()
2673
- {
2674
- int maxWait;
2675
- int sec =0;
2676
- g_prefork_server->m_iMaxReqProcessTime = 10;
2677
- g_prefork_server->m_iMaxIdleChildren = -1;
2678
- maxWait = 15;
2679
3065
 
2680
- while( g_prefork_server->m_iCurChildren && (sec < maxWait) )
2681
- {
2682
- lsapi_check_child_status(time(NULL));
2683
- sleep( 1 );
2684
- sec++;
2685
- }
2686
- if ( g_prefork_server->m_iCurChildren != 0 )
2687
- kill( -getpgrp(), SIGKILL );
2688
- return 0;
2689
- }
3066
+ //static int lsapi_all_children_must_die(void)
3067
+ //{
3068
+ // int maxWait;
3069
+ // int sec =0;
3070
+ // g_prefork_server->m_iMaxReqProcessTime = 10;
3071
+ // g_prefork_server->m_iMaxIdleChildren = -1;
3072
+ // maxWait = 15;
3073
+ //
3074
+ // while( g_prefork_server->m_iCurChildren && (sec < maxWait) )
3075
+ // {
3076
+ // lsapi_check_child_status(time(NULL));
3077
+ // sleep( 1 );
3078
+ // sec++;
3079
+ // }
3080
+ // if ( g_prefork_server->m_iCurChildren != 0 )
3081
+ // kill( -getpgrp(), SIGKILL );
3082
+ // return 0;
3083
+ //}
3084
+
2690
3085
 
3086
+ void set_skip_write()
3087
+ { s_skip_write = 1; }
3088
+
3089
+
3090
+ int is_enough_free_mem()
3091
+ {
3092
+ #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
3093
+ //minimum 1GB or 10% available free memory
3094
+ return (*s_avail_pages > s_min_avail_pages
3095
+ || (*s_avail_pages * 10) / s_total_pages > 0);
3096
+ #endif
3097
+ return 1;
3098
+ }
2691
3099
 
2692
3100
 
2693
- static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Request * pReq )
3101
+ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer,
3102
+ LSAPI_Request * pReq )
2694
3103
  {
2695
3104
  struct sigaction act, old_term, old_quit, old_int,
2696
3105
  old_usr1, old_child;
@@ -2707,11 +3116,10 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2707
3116
  sigset_t orig_mask;
2708
3117
 
2709
3118
  lsapi_init_children_status();
2710
-
2711
- setsid();
2712
3119
 
2713
3120
  act.sa_flags = 0;
2714
3121
  act.sa_handler = lsapi_sigchild;
3122
+ sigemptyset(&(act.sa_mask));
2715
3123
  if( sigaction( SIGCHLD, &act, &old_child ) )
2716
3124
  {
2717
3125
  perror( "Can't set signal handler for SIGCHILD" );
@@ -2721,6 +3129,7 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2721
3129
  /* Set up handler to kill children upon exit */
2722
3130
  act.sa_flags = 0;
2723
3131
  act.sa_handler = lsapi_cleanup;
3132
+ sigemptyset(&(act.sa_mask));
2724
3133
  if( sigaction( SIGTERM, &act, &old_term ) ||
2725
3134
  sigaction( SIGINT, &act, &old_int ) ||
2726
3135
  sigaction( SIGUSR1, &act, &old_usr1 ) ||
@@ -2729,14 +3138,18 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2729
3138
  perror( "Can't set signals" );
2730
3139
  return -1;
2731
3140
  }
2732
- s_stop = 0;
3141
+
2733
3142
  while( !s_stop )
2734
3143
  {
3144
+ if (s_proc_group_timer_cb != NULL) {
3145
+ s_proc_group_timer_cb(&s_ignore_pid);
3146
+ }
3147
+
2735
3148
  curTime = time( NULL );
2736
3149
  if (curTime != lastTime )
2737
3150
  {
2738
3151
  lastTime = curTime;
2739
- if (s_ppid && (getppid() != s_ppid ))
3152
+ if (lsapi_parent_dead())
2740
3153
  break;
2741
3154
  lsapi_check_child_status(curTime );
2742
3155
  if (pServer->m_iServerMaxIdle)
@@ -2752,29 +3165,31 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2752
3165
  }
2753
3166
  }
2754
3167
 
2755
- if ( pServer->m_iCurChildren >= (pServer->m_iMaxChildren + pServer->m_iExtraChildren ) )
2756
- {
2757
- fprintf( stderr, "Reached max children process limit: %d, extra: %d, current: %d, please increase LSAPI_CHILDREN.\n",
2758
- pServer->m_iMaxChildren, pServer->m_iExtraChildren, pServer->m_iCurChildren );
2759
- usleep( 100000 );
2760
- continue;
2761
- }
3168
+ #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
3169
+ *s_avail_pages = sysconf(_SC_AVPHYS_PAGES);
3170
+ // lsapi_log("Memory total: %zd, free: %zd, free %%%zd\n",
3171
+ // s_total_pages, *s_avail_pages, *s_avail_pages * 100 / s_total_pages);
2762
3172
 
3173
+ #endif
2763
3174
  FD_ZERO( &readfds );
2764
3175
  FD_SET( pServer->m_fd, &readfds );
2765
- timeout.tv_sec = 1; timeout.tv_usec = 0;
2766
- if ((ret = (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout)) == 1 )
3176
+ timeout.tv_sec = 1;
3177
+ timeout.tv_usec = 0;
3178
+ ret = (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout);
3179
+ if (ret == 1 )
2767
3180
  {
2768
- /*
2769
- if ( pServer->m_iCurChildren >= 0 )
3181
+ int accepting = 0;
3182
+ if (s_accepting_workers)
3183
+ accepting = __sync_add_and_fetch(s_accepting_workers, 0);
3184
+
3185
+ if (pServer->m_iCurChildren > 0
3186
+ && accepting > 0)
2770
3187
  {
2771
- usleep( 10 );
2772
- FD_ZERO( &readfds );
2773
- FD_SET( pServer->m_fd, &readfds );
2774
- timeout.tv_sec = 0; timeout.tv_usec = 0;
2775
- if ( (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout) == 0 )
2776
- continue;
2777
- }*/
3188
+ usleep( 400);
3189
+ while(accepting-- > 0)
3190
+ sched_yield();
3191
+ continue;
3192
+ }
2778
3193
  }
2779
3194
  else if ( ret == -1 )
2780
3195
  {
@@ -2788,33 +3203,60 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2788
3203
  continue;
2789
3204
  }
2790
3205
 
3206
+ if (pServer->m_iCurChildren >=
3207
+ pServer->m_iMaxChildren + pServer->m_iExtraChildren)
3208
+ {
3209
+ lsapi_log("Reached max children process limit: %d, extra: %d,"
3210
+ " current: %d, busy: %d, please increase LSAPI_CHILDREN.\n",
3211
+ pServer->m_iMaxChildren, pServer->m_iExtraChildren,
3212
+ pServer->m_iCurChildren,
3213
+ s_busy_workers ? *s_busy_workers : -1 );
3214
+ usleep( 100000 );
3215
+ continue;
3216
+ }
3217
+
2791
3218
  pReq->m_fd = lsapi_accept( pServer->m_fd );
2792
3219
  if ( pReq->m_fd != -1 )
2793
3220
  {
3221
+ wait_secs = 0;
2794
3222
  child_status = find_child_status( 0 );
2795
- if ( child_status )
2796
- memset( child_status, 0, sizeof( *child_status ) );
2797
3223
 
2798
3224
  sigemptyset( &mask );
2799
3225
  sigaddset( &mask, SIGCHLD );
2800
-
2801
- if ( sigprocmask(SIG_BLOCK, &mask, &orig_mask) < 0 )
3226
+
3227
+ if ( sigprocmask(SIG_BLOCK, &mask, &orig_mask) < 0 )
2802
3228
  {
2803
3229
  perror( "sigprocmask(SIG_BLOCK) to block SIGCHLD" );
2804
3230
  }
2805
3231
 
2806
3232
  pid = fork();
2807
-
3233
+
2808
3234
  if ( !pid )
2809
3235
  {
2810
- if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) < 0)
3236
+ setsid();
3237
+ if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) < 0)
2811
3238
  perror( "sigprocmask( SIG_SETMASK ) to restore SIGMASK in child" );
2812
3239
  g_prefork_server = NULL;
2813
3240
  s_ppid = getppid();
3241
+ s_pid = getpid();
2814
3242
  s_req_processed = 0;
2815
- s_pChildStatus = child_status;
3243
+ s_proc_group_timer_cb = NULL;
3244
+ s_worker_status = child_status;
3245
+
3246
+ if (pthread_atfork_func)
3247
+ (*pthread_atfork_func)(NULL, NULL, set_skip_write);
3248
+
3249
+ __sync_lock_test_and_set(&s_worker_status->m_state,
3250
+ LSAPI_STATE_CONNECTED);
3251
+ if (s_busy_workers)
3252
+ __sync_add_and_fetch(s_busy_workers, 1);
2816
3253
  lsapi_set_nblock( pReq->m_fd, 0 );
2817
- if ( pReq->m_fdListen != -1 )
3254
+ //keep it open if busy_count is used.
3255
+ if (s_busy_workers
3256
+ && *s_busy_workers > (pServer->m_iMaxChildren >> 1))
3257
+ s_keepListener = 1;
3258
+ if ((s_uid == 0 || !s_keepListener || !is_enough_free_mem())
3259
+ && pReq->m_fdListen != -1 )
2818
3260
  {
2819
3261
  close( pReq->m_fdListen );
2820
3262
  pReq->m_fdListen = -1;
@@ -2834,7 +3276,9 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2834
3276
  }
2835
3277
  else if ( pid == -1 )
2836
3278
  {
2837
- perror( "fork() failed, please increase process limit" );
3279
+ lsapi_perror("fork() failed, please increase process limit", errno);
3280
+ if (child_status)
3281
+ child_status->m_pid = 0;
2838
3282
  }
2839
3283
  else
2840
3284
  {
@@ -2849,7 +3293,7 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2849
3293
  close( pReq->m_fd );
2850
3294
  pReq->m_fd = -1;
2851
3295
 
2852
- if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) < 0)
3296
+ if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) < 0)
2853
3297
  perror( "sigprocmask( SIG_SETMASK ) to restore SIGMASK" );
2854
3298
 
2855
3299
  }
@@ -2857,7 +3301,7 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2857
3301
  {
2858
3302
  if (( errno == EINTR )||( errno == EAGAIN))
2859
3303
  continue;
2860
- perror( "accept() failed" );
3304
+ lsapi_perror("accept() failed", errno);
2861
3305
  return -1;
2862
3306
  }
2863
3307
  }
@@ -2868,11 +3312,211 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2868
3312
 
2869
3313
  }
2870
3314
 
2871
- void lsapi_error( const char * pMessage, int err_no )
3315
+
3316
+ static struct sigaction old_term, old_quit, old_int,
3317
+ old_usr1, old_child;
3318
+
3319
+
3320
+ int LSAPI_Postfork_Child(LSAPI_Request * pReq)
2872
3321
  {
2873
- fprintf( stderr, "%d: %s, errno: %d (%s)\n", getpid(), pMessage, err_no, strerror( err_no ) );
3322
+ int max_children = g_prefork_server->m_iMaxChildren;
3323
+ s_pid = getpid();
3324
+ __sync_lock_test_and_set(&pReq->child_status->m_pid, s_pid);
3325
+ s_worker_status = pReq->child_status;
3326
+
3327
+ setsid();
3328
+ g_prefork_server = NULL;
3329
+ s_ppid = getppid();
3330
+ s_req_processed = 0;
3331
+ s_proc_group_timer_cb = NULL;
3332
+
3333
+ if (pthread_atfork_func)
3334
+ (*pthread_atfork_func)(NULL, NULL, set_skip_write);
3335
+
3336
+ __sync_lock_test_and_set(&s_worker_status->m_state,
3337
+ LSAPI_STATE_CONNECTED);
3338
+ if (s_busy_workers)
3339
+ __sync_add_and_fetch(s_busy_workers, 1);
3340
+ lsapi_set_nblock( pReq->m_fd, 0 );
3341
+ //keep it open if busy_count is used.
3342
+ if (s_busy_workers
3343
+ && *s_busy_workers > (max_children >> 1))
3344
+ s_keepListener = 1;
3345
+ if ((s_uid == 0 || !s_keepListener || !is_enough_free_mem())
3346
+ && pReq->m_fdListen != -1 )
3347
+ {
3348
+ close(pReq->m_fdListen);
3349
+ pReq->m_fdListen = -1;
3350
+ }
3351
+
3352
+ //init_conn_key( pReq->m_fd );
3353
+ lsapi_notify_pid(pReq->m_fd);
3354
+ s_notified_pid = 1;
3355
+ //if ( s_accept_notify )
3356
+ // return notify_req_received( pReq->m_fd );
3357
+ return 0;
3358
+ }
3359
+
3360
+
3361
+ int LSAPI_Postfork_Parent(LSAPI_Request * pReq)
3362
+ {
3363
+ ++g_prefork_server->m_iCurChildren;
3364
+ if (pReq->child_status)
3365
+ {
3366
+ time_t curTime = time( NULL );
3367
+ pReq->child_status->m_tmWaitBegin = curTime;
3368
+ pReq->child_status->m_tmStart = curTime;
3369
+ }
3370
+ close(pReq->m_fd);
3371
+ pReq->m_fd = -1;
3372
+ return 0;
3373
+ }
3374
+
3375
+
3376
+ int LSAPI_Accept_Before_Fork(LSAPI_Request * pReq)
3377
+ {
3378
+ time_t lastTime = 0;
3379
+ time_t curTime = 0;
3380
+ fd_set readfds;
3381
+ struct timeval timeout;
3382
+ int wait_secs = 0;
3383
+ int ret = 0;
3384
+
3385
+ lsapi_prefork_server * pServer = g_prefork_server;
3386
+
3387
+ struct sigaction act;
3388
+
3389
+ lsapi_init_children_status();
3390
+
3391
+ act.sa_flags = 0;
3392
+ act.sa_handler = lsapi_sigchild;
3393
+ sigemptyset(&(act.sa_mask));
3394
+ if (sigaction(SIGCHLD, &act, &old_child))
3395
+ {
3396
+ perror( "Can't set signal handler for SIGCHILD" );
3397
+ return -1;
3398
+ }
3399
+
3400
+ /* Set up handler to kill children upon exit */
3401
+ act.sa_flags = 0;
3402
+ act.sa_handler = lsapi_cleanup;
3403
+ sigemptyset(&(act.sa_mask));
3404
+ if (sigaction(SIGTERM, &act, &old_term) ||
3405
+ sigaction(SIGINT, &act, &old_int ) ||
3406
+ sigaction(SIGUSR1, &act, &old_usr1) ||
3407
+ sigaction(SIGQUIT, &act, &old_quit))
3408
+ {
3409
+ perror( "Can't set signals" );
3410
+ return -1;
3411
+ }
3412
+ s_stop = 0;
3413
+ pReq->m_reqState = 0;
3414
+
3415
+ while(!s_stop)
3416
+ {
3417
+ if (s_proc_group_timer_cb != NULL) {
3418
+ s_proc_group_timer_cb(&s_ignore_pid);
3419
+ }
3420
+
3421
+ curTime = time(NULL);
3422
+ if (curTime != lastTime)
3423
+ {
3424
+ lastTime = curTime;
3425
+ if (lsapi_parent_dead())
3426
+ break;
3427
+ lsapi_check_child_status(curTime);
3428
+ if (pServer->m_iServerMaxIdle)
3429
+ {
3430
+ if (pServer->m_iCurChildren <= 0)
3431
+ {
3432
+ ++wait_secs;
3433
+ if ( wait_secs > pServer->m_iServerMaxIdle )
3434
+ return -1;
3435
+ }
3436
+ else
3437
+ wait_secs = 0;
3438
+ }
3439
+ }
3440
+
3441
+ #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
3442
+ *s_avail_pages = sysconf(_SC_AVPHYS_PAGES);
3443
+ // lsapi_log("Memory total: %zd, free: %zd, free %%%zd\n",
3444
+ // s_total_pages, *s_avail_pages, *s_avail_pages * 100 / s_total_pages);
3445
+
3446
+ #endif
3447
+ FD_ZERO(&readfds);
3448
+ FD_SET(pServer->m_fd, &readfds);
3449
+ timeout.tv_sec = 1;
3450
+ timeout.tv_usec = 0;
3451
+ ret = (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout);
3452
+ if (ret == 1 )
3453
+ {
3454
+ int accepting = 0;
3455
+ if (s_accepting_workers)
3456
+ accepting = __sync_add_and_fetch(s_accepting_workers, 0);
3457
+
3458
+ if (pServer->m_iCurChildren > 0
3459
+ && accepting > 0)
3460
+ {
3461
+ usleep( 400);
3462
+ while(accepting-- > 0)
3463
+ sched_yield();
3464
+ continue;
3465
+ }
3466
+ }
3467
+ else if (ret == -1)
3468
+ {
3469
+ if (errno == EINTR)
3470
+ continue;
3471
+ /* perror( "select()" ); */
3472
+ break;
3473
+ }
3474
+ else
3475
+ {
3476
+ continue;
3477
+ }
3478
+
3479
+ if (pServer->m_iCurChildren >=
3480
+ pServer->m_iMaxChildren + pServer->m_iExtraChildren)
3481
+ {
3482
+ lsapi_log("Reached max children process limit: %d, extra: %d,"
3483
+ " current: %d, busy: %d, please increase LSAPI_CHILDREN.\n",
3484
+ pServer->m_iMaxChildren, pServer->m_iExtraChildren,
3485
+ pServer->m_iCurChildren,
3486
+ s_busy_workers ? *s_busy_workers : -1);
3487
+ usleep(100000);
3488
+ continue;
3489
+ }
3490
+
3491
+ pReq->m_fd = lsapi_accept(pServer->m_fd);
3492
+ if (pReq->m_fd != -1)
3493
+ {
3494
+ wait_secs = 0;
3495
+ pReq->child_status = find_child_status(0);
3496
+
3497
+ ret = 0;
3498
+ break;
3499
+ }
3500
+ else
3501
+ {
3502
+ if ((errno == EINTR) || (errno == EAGAIN))
3503
+ continue;
3504
+ lsapi_perror("accept() failed", errno);
3505
+ ret = -1;
3506
+ break;
3507
+ }
3508
+ }
3509
+
3510
+ sigaction(SIGCHLD, &old_child, 0);
3511
+ sigaction(SIGTERM, &old_term, 0);
3512
+ sigaction(SIGQUIT, &old_quit, 0);
3513
+ sigaction(SIGINT, &old_int, 0);
3514
+ sigaction(SIGUSR1, &old_usr1, 0);
3515
+
3516
+ return ret;
2874
3517
  }
2875
3518
 
3519
+
2876
3520
  int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
2877
3521
  {
2878
3522
  int fd;
@@ -2881,8 +3525,10 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
2881
3525
  fd_set readfds;
2882
3526
  struct timeval timeout;
2883
3527
 
2884
- LSAPI_Finish_r( pReq );
3528
+ if (s_skip_write)
3529
+ return -1;
2885
3530
 
3531
+ LSAPI_Finish_r( pReq );
2886
3532
 
2887
3533
  if ( g_prefork_server )
2888
3534
  {
@@ -2890,15 +3536,25 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
2890
3536
  if ( lsapi_prefork_server_accept( g_prefork_server, pReq ) == -1 )
2891
3537
  return -1;
2892
3538
  }
2893
- if ( s_req_processed >= s_max_reqs )
3539
+ else if (s_req_processed > 0 && s_max_busy_workers > 0 && s_busy_workers)
3540
+ {
3541
+ ret = __sync_fetch_and_add(s_busy_workers, 0);
3542
+ if (ret >= s_max_busy_workers)
3543
+ {
3544
+ send_conn_close_notification(pReq->m_fd);
3545
+ lsapi_close_connection(pReq);
3546
+ }
3547
+ }
3548
+
3549
+ if ( (unsigned int)s_req_processed > s_max_reqs )
2894
3550
  return -1;
2895
3551
 
2896
- if ( s_pChildStatus )
3552
+ if ( s_worker_status )
2897
3553
  {
2898
- s_pChildStatus->m_tmWaitBegin = time( NULL );
3554
+ s_worker_status->m_tmWaitBegin = time( NULL );
2899
3555
  }
2900
3556
 
2901
-
3557
+
2902
3558
  while( g_running )
2903
3559
  {
2904
3560
  if ( pReq->m_fd != -1 )
@@ -2916,23 +3572,44 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
2916
3572
  {
2917
3573
  if ( !g_running )
2918
3574
  return -1;
2919
- if ((s_req_processed)&&( s_pChildStatus )&&( s_pChildStatus->m_iKillSent ))
2920
- return -1;
3575
+ if (s_req_processed && s_worker_status
3576
+ && s_worker_status->m_iKillSent)
3577
+ return -1;
2921
3578
  FD_ZERO( &readfds );
2922
3579
  FD_SET( fd, &readfds );
2923
3580
  timeout.tv_sec = 1;
2924
3581
  timeout.tv_usec = 0;
3582
+ if (fd == pReq->m_fdListen)
3583
+ {
3584
+ if (s_worker_status)
3585
+ __sync_lock_test_and_set(&s_worker_status->m_state,
3586
+ LSAPI_STATE_ACCEPTING);
3587
+ if (s_accepting_workers)
3588
+ __sync_fetch_and_add(s_accepting_workers, 1);
3589
+ }
2925
3590
  ret = (*g_fnSelect)(fd+1, &readfds, NULL, NULL, &timeout);
3591
+ if (fd == pReq->m_fdListen)
3592
+ {
3593
+ if (s_accepting_workers)
3594
+ __sync_fetch_and_sub(s_accepting_workers, 1);
3595
+ if (s_worker_status)
3596
+ __sync_lock_test_and_set(&s_worker_status->m_state,
3597
+ LSAPI_STATE_IDLE);
3598
+ }
3599
+
2926
3600
  if ( ret == 0 )
2927
3601
  {
2928
- if ( s_pChildStatus )
3602
+ if ( s_worker_status )
2929
3603
  {
2930
- s_pChildStatus->m_inProcess = 0;
3604
+ s_worker_status->m_inProcess = 0;
3605
+ if (fd == pReq->m_fdListen
3606
+ && (s_keepListener != 2 || !is_enough_free_mem()))
3607
+ return -1;
2931
3608
  }
2932
3609
  ++wait_secs;
2933
3610
  if (( s_max_idle_secs > 0 )&&(wait_secs >= s_max_idle_secs ))
2934
3611
  return -1;
2935
- if ( s_ppid &&( getppid() != s_ppid))
3612
+ if ( lsapi_parent_dead() )
2936
3613
  return -1;
2937
3614
  }
2938
3615
  else if ( ret == -1 )
@@ -2944,17 +3621,25 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
2944
3621
  }
2945
3622
  else if ( ret >= 1 )
2946
3623
  {
2947
- if (s_req_processed && ( s_pChildStatus )&&( s_pChildStatus->m_iKillSent ))
2948
- return -1;
3624
+ if (s_req_processed && s_worker_status
3625
+ && s_worker_status->m_iKillSent)
3626
+ return -1;
2949
3627
  if ( fd == pReq->m_fdListen )
2950
3628
  {
2951
3629
  pReq->m_fd = lsapi_accept( pReq->m_fdListen );
2952
3630
  if ( pReq->m_fd != -1 )
2953
3631
  {
3632
+ if (s_worker_status)
3633
+ __sync_lock_test_and_set(&s_worker_status->m_state,
3634
+ LSAPI_STATE_CONNECTED);
3635
+ if (s_busy_workers)
3636
+ __sync_fetch_and_add(s_busy_workers, 1);
3637
+
2954
3638
  fd = pReq->m_fd;
3639
+
2955
3640
  lsapi_set_nblock( fd, 0 );
2956
3641
  //init_conn_key( pReq->m_fd );
2957
- if ( !s_keepListener )
3642
+ if (!s_keepListener)
2958
3643
  {
2959
3644
  close( pReq->m_fdListen );
2960
3645
  pReq->m_fdListen = -1;
@@ -2967,7 +3652,7 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
2967
3652
  {
2968
3653
  if (( errno == EINTR )||( errno == EAGAIN))
2969
3654
  continue;
2970
- lsapi_error( "lsapi_accept() error", errno );
3655
+ lsapi_perror( "lsapi_accept() error", errno );
2971
3656
  return -1;
2972
3657
  }
2973
3658
  }
@@ -2978,42 +3663,46 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
2978
3663
 
2979
3664
  if ( !readReq( pReq ) )
2980
3665
  {
2981
- if ( s_pChildStatus )
3666
+ if ( s_worker_status )
2982
3667
  {
2983
- s_pChildStatus->m_iKillSent = 0;
2984
- s_pChildStatus->m_inProcess = 1;
2985
- ++s_pChildStatus->m_iReqCounter;
2986
- s_pChildStatus->m_tmReqBegin = s_pChildStatus->m_tmLastCheckPoint = time(NULL);
3668
+ s_worker_status->m_iKillSent = 0;
3669
+ s_worker_status->m_inProcess = 1;
3670
+ ++s_worker_status->m_iReqCounter;
3671
+ s_worker_status->m_tmReqBegin =
3672
+ s_worker_status->m_tmLastCheckPoint = time(NULL);
2987
3673
  }
2988
3674
  ++s_req_processed;
2989
3675
  return 0;
2990
3676
  }
2991
- lsapi_close( pReq->m_fd );
2992
- pReq->m_fd = -1;
3677
+ lsapi_close_connection(pReq);
2993
3678
  LSAPI_Reset_r( pReq );
2994
3679
  }
2995
3680
  return -1;
2996
-
3681
+
2997
3682
  }
2998
3683
 
3684
+
2999
3685
  void LSAPI_Set_Max_Reqs( int reqs )
3000
- { s_max_reqs = reqs; }
3686
+ { s_max_reqs = reqs - 1; }
3001
3687
 
3002
3688
  void LSAPI_Set_Max_Idle( int secs )
3003
3689
  { s_max_idle_secs = secs; }
3004
3690
 
3691
+
3005
3692
  void LSAPI_Set_Max_Children( int maxChildren )
3006
3693
  {
3007
3694
  if ( g_prefork_server )
3008
3695
  g_prefork_server->m_iMaxChildren = maxChildren;
3009
3696
  }
3010
3697
 
3698
+
3011
3699
  void LSAPI_Set_Extra_Children( int extraChildren )
3012
3700
  {
3013
3701
  if (( g_prefork_server )&&( extraChildren >= 0 ))
3014
3702
  g_prefork_server->m_iExtraChildren = extraChildren;
3015
3703
  }
3016
3704
 
3705
+
3017
3706
  void LSAPI_Set_Max_Process_Time( int secs )
3018
3707
  {
3019
3708
  if (( g_prefork_server )&&( secs > 0 ))
@@ -3027,34 +3716,44 @@ void LSAPI_Set_Max_Idle_Children( int maxIdleChld )
3027
3716
  g_prefork_server->m_iMaxIdleChildren = maxIdleChld;
3028
3717
  }
3029
3718
 
3719
+
3030
3720
  void LSAPI_Set_Server_Max_Idle_Secs( int serverMaxIdle )
3031
3721
  {
3032
3722
  if ( g_prefork_server )
3033
3723
  g_prefork_server->m_iServerMaxIdle = serverMaxIdle;
3034
3724
  }
3035
3725
 
3726
+
3036
3727
  void LSAPI_Set_Slow_Req_Msecs( int msecs )
3037
3728
  {
3038
3729
  s_slow_req_msecs = msecs;
3039
3730
  }
3040
3731
 
3041
- int LSAPI_Get_Slow_Req_Msecs()
3732
+
3733
+ int LSAPI_Get_Slow_Req_Msecs(void)
3042
3734
  {
3043
3735
  return s_slow_req_msecs;
3044
3736
  }
3045
3737
 
3046
3738
 
3047
- void LSAPI_No_Check_ppid()
3739
+ void LSAPI_No_Check_ppid(void)
3048
3740
  {
3049
3741
  s_ppid = 0;
3050
3742
  }
3051
3743
 
3744
+
3745
+ int LSAPI_Get_ppid()
3746
+ {
3747
+ return(s_ppid);
3748
+ }
3749
+
3750
+
3052
3751
  #if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
3053
3752
  #include <crt_externs.h>
3054
3753
  #else
3055
3754
  extern char ** environ;
3056
3755
  #endif
3057
- static void unset_lsapi_envs()
3756
+ static void unset_lsapi_envs(void)
3058
3757
  {
3059
3758
  char **env;
3060
3759
  #if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
@@ -3062,22 +3761,23 @@ static void unset_lsapi_envs()
3062
3761
  #else
3063
3762
  env = environ;
3064
3763
  #endif
3065
- while( env != NULL && *env != NULL )
3764
+ while( env != NULL && *env != NULL )
3066
3765
  {
3067
- if (!strncmp(*env, "LSAPI_", 6) || !strncmp( *env, "PHP_LSAPI_", 10 )
3068
- || (!strncmp( *env, "PHPRC=", 6 )&&(!s_uid)))
3069
- {
3766
+ if (!strncmp(*env, "LSAPI_", 6) || !strncmp( *env, "PHP_LSAPI_", 10 )
3767
+ || (!strncmp( *env, "PHPRC=", 6 )&&(!s_uid)))
3768
+ {
3070
3769
  char ** del = env;
3071
- do
3770
+ do
3072
3771
  *del = del[1];
3073
3772
  while( *del++ );
3074
3773
  }
3075
3774
  else
3076
3775
  ++env;
3077
- }
3776
+ }
3078
3777
  }
3079
3778
 
3080
- static int lsapi_initSuEXEC()
3779
+
3780
+ static int lsapi_initSuEXEC(void)
3081
3781
  {
3082
3782
  int i;
3083
3783
  struct passwd * pw;
@@ -3101,7 +3801,7 @@ static int lsapi_initSuEXEC()
3101
3801
  }
3102
3802
  p = getenv( "LSAPI_SECRET" );
3103
3803
  if (( !p )||( readSecret(p) == -1 ))
3104
- return -1;
3804
+ return -1;
3105
3805
  if ( g_prefork_server )
3106
3806
  {
3107
3807
  if ( g_prefork_server->m_iMaxChildren < 100 )
@@ -3113,20 +3813,110 @@ static int lsapi_initSuEXEC()
3113
3813
  if ( !s_defaultUid || !s_defaultGid )
3114
3814
  {
3115
3815
  pw = getpwnam( "nobody" );
3116
- if ( !s_defaultUid )
3117
- s_defaultUid = pw->pw_uid;
3118
- if ( !s_defaultGid )
3119
- s_defaultGid = pw->pw_gid;
3816
+ if ( pw )
3817
+ {
3818
+ if ( !s_defaultUid )
3819
+ s_defaultUid = pw->pw_uid;
3820
+ if ( !s_defaultGid )
3821
+ s_defaultGid = pw->pw_gid;
3822
+ }
3823
+ else
3824
+ {
3825
+ if ( !s_defaultUid )
3826
+ s_defaultUid = 10000;
3827
+ if ( !s_defaultGid )
3828
+ s_defaultGid = 10000;
3829
+ }
3120
3830
  }
3121
3831
  return 0;
3122
3832
  }
3123
3833
 
3124
3834
 
3835
+ static int lsapi_check_path(const char *p, char *final, int max_len)
3836
+ {
3837
+ char resolved_path[PATH_MAX+1];
3838
+ int len = 0;
3839
+ char *end;
3840
+ if (*p != '/')
3841
+ {
3842
+ if (getcwd(final, max_len) == NULL)
3843
+ return -1;
3844
+ len = strlen(final);
3845
+ *(final + len) = '/';
3846
+ ++len;
3847
+ }
3848
+ end = memccpy(&final[len], p, '\0', PATH_MAX - len);
3849
+ if (!end)
3850
+ {
3851
+ errno = EINVAL;
3852
+ return -1;
3853
+ }
3854
+ p = final;
3855
+ if (realpath(p, resolved_path) == NULL
3856
+ && errno != ENOENT && errno != EACCES)
3857
+ return -1;
3858
+ if (strncmp(resolved_path, "/etc/", 5) == 0)
3859
+ {
3860
+ errno = EPERM;
3861
+ return -1;
3862
+ }
3863
+ return 0;
3864
+ }
3865
+
3866
+
3867
+ static int lsapi_reopen_stderr2(const char *full_path)
3868
+ {
3869
+ int newfd = open(full_path, O_WRONLY | O_CREAT | O_APPEND, 0644);
3870
+ if (newfd == -1)
3871
+ {
3872
+ LSAPI_perror_r(NULL, "Failed to open custom stderr log", full_path);
3873
+ return -1;
3874
+ }
3875
+ if (newfd != 2)
3876
+ {
3877
+ dup2(newfd, 2);
3878
+ close(newfd);
3879
+ dup2(2, 1);
3880
+ }
3881
+ if (s_stderr_log_path && full_path != s_stderr_log_path)
3882
+ {
3883
+ free(s_stderr_log_path);
3884
+ s_stderr_log_path = NULL;
3885
+ }
3886
+ s_stderr_log_path = strdup(full_path);
3887
+ return 0;
3888
+ }
3889
+
3890
+
3891
+ static int lsapi_reopen_stderr(const char *p)
3892
+ {
3893
+ char full_path[PATH_MAX];
3894
+ if (s_uid == 0)
3895
+ return -1;
3896
+ if (lsapi_check_path(p, full_path, PATH_MAX) == -1)
3897
+ {
3898
+ LSAPI_perror_r(NULL, "Invalid custom stderr log path", p);
3899
+ return -1;
3900
+ }
3901
+ return lsapi_reopen_stderr2(full_path);
3902
+ }
3903
+
3904
+
3125
3905
  int LSAPI_Init_Env_Parameters( fn_select_t fp )
3126
3906
  {
3127
3907
  const char *p;
3908
+ char ch;
3128
3909
  int n;
3129
3910
  int avoidFork = 0;
3911
+
3912
+ p = getenv("LSAPI_STDERR_LOG");
3913
+ if (p)
3914
+ {
3915
+ lsapi_reopen_stderr(p);
3916
+ }
3917
+ if (!s_stderr_log_path)
3918
+ s_stderr_is_pipe = isPipe(STDERR_FILENO);
3919
+
3130
3920
  p = getenv( "PHP_LSAPI_MAX_REQUESTS" );
3131
3921
  if ( !p )
3132
3922
  p = getenv( "LSAPI_MAX_REQS" );
@@ -3137,11 +3927,29 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp )
3137
3927
  LSAPI_Set_Max_Reqs( n );
3138
3928
  }
3139
3929
 
3930
+ p = getenv( "LSAPI_KEEP_LISTEN" );
3931
+ if ( p )
3932
+ {
3933
+ n = atoi( p );
3934
+ s_keepListener = n;
3935
+ }
3936
+
3140
3937
  p = getenv( "LSAPI_AVOID_FORK" );
3141
3938
  if ( p )
3142
3939
  {
3143
3940
  avoidFork = atoi( p );
3144
- }
3941
+ if (avoidFork)
3942
+ {
3943
+ s_keepListener = 2;
3944
+ ch = *(p + strlen(p) - 1);
3945
+ if ( ch == 'G' || ch == 'g' )
3946
+ avoidFork *= 1024 * 1024 * 1024;
3947
+ else if ( ch == 'M' || ch == 'm' )
3948
+ avoidFork *= 1024 * 1024;
3949
+ if (avoidFork >= 1024 * 10240)
3950
+ s_min_avail_pages = avoidFork / 4096;
3951
+ }
3952
+ }
3145
3953
 
3146
3954
  p = getenv( "LSAPI_ACCEPT_NOTIFY" );
3147
3955
  if ( p )
@@ -3150,7 +3958,7 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp )
3150
3958
  }
3151
3959
 
3152
3960
  p = getenv( "LSAPI_SLOW_REQ_MSECS" );
3153
- if ( p )
3961
+ if ( p )
3154
3962
  {
3155
3963
  n = atoi( p );
3156
3964
  LSAPI_Set_Slow_Req_Msecs( n );
@@ -3175,14 +3983,6 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp )
3175
3983
  LSAPI_Set_Max_Idle( n );
3176
3984
  }
3177
3985
 
3178
- p = getenv( "LSAPI_KEEP_LISTEN" );
3179
- if ( p )
3180
- {
3181
- n = atoi( p );
3182
- s_keepListener = n;
3183
- }
3184
-
3185
-
3186
3986
  if ( LSAPI_Is_Listen() )
3187
3987
  {
3188
3988
  n = 0;
@@ -3193,33 +3993,43 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp )
3193
3993
  n = atoi( p );
3194
3994
  if ( n > 1 )
3195
3995
  {
3196
- LSAPI_Init_Prefork_Server( n, fp, avoidFork );
3996
+ LSAPI_Init_Prefork_Server( n, fp, avoidFork != 0 );
3197
3997
  LSAPI_Set_Server_fd( g_req.m_fdListen );
3198
3998
  }
3199
3999
 
3200
4000
  p = getenv( "LSAPI_EXTRA_CHILDREN" );
3201
4001
  if ( p )
3202
4002
  LSAPI_Set_Extra_Children( atoi( p ) );
3203
-
4003
+
3204
4004
  p = getenv( "LSAPI_MAX_IDLE_CHILDREN" );
3205
4005
  if ( p )
3206
4006
  LSAPI_Set_Max_Idle_Children( atoi( p ) );
3207
-
4007
+
3208
4008
  p = getenv( "LSAPI_PGRP_MAX_IDLE" );
3209
4009
  if ( p )
3210
4010
  {
3211
4011
  LSAPI_Set_Server_Max_Idle_Secs( atoi( p ) );
3212
4012
  }
3213
-
4013
+
3214
4014
  p = getenv( "LSAPI_MAX_PROCESS_TIME" );
3215
- if ( p )
4015
+ if ( p )
3216
4016
  LSAPI_Set_Max_Process_Time( atoi( p ) );
3217
-
4017
+
3218
4018
  if ( getenv( "LSAPI_PPID_NO_CHECK" ) )
3219
4019
  {
3220
4020
  LSAPI_No_Check_ppid();
3221
4021
  }
3222
4022
 
4023
+ p = getenv("LSAPI_MAX_BUSY_WORKER");
4024
+ if (p)
4025
+ {
4026
+ n = atoi(p);
4027
+ s_max_busy_workers = n;
4028
+ if (n >= 0)
4029
+ LSAPI_No_Check_ppid();
4030
+ }
4031
+
4032
+
3223
4033
  p = getenv( "LSAPI_DUMP_DEBUG_INFO" );
3224
4034
  if ( p )
3225
4035
  s_dump_debug_info = atoi( p );
@@ -3235,7 +4045,7 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp )
3235
4045
  }
3236
4046
 
3237
4047
 
3238
- int LSAPI_ErrResponse_r( LSAPI_Request * pReq, int code, const char ** pRespHeaders,
4048
+ int LSAPI_ErrResponse_r( LSAPI_Request * pReq, int code, const char ** pRespHeaders,
3239
4049
  const char * pBody, int bodyLen )
3240
4050
  {
3241
4051
  LSAPI_SetRespStatus_r( pReq, code );
@@ -3272,6 +4082,7 @@ static void byteReverse(unsigned char *buf, unsigned longs)
3272
4082
  } while (--longs);
3273
4083
  }
3274
4084
 
4085
+
3275
4086
  /*
3276
4087
  * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
3277
4088
  * initialization constants.
@@ -3335,6 +4146,7 @@ void lsapi_MD5Update(struct lsapi_MD5Context *ctx, unsigned char const *buf, uns
3335
4146
  memmove(ctx->in, buf, len);
3336
4147
  }
3337
4148
 
4149
+
3338
4150
  /*
3339
4151
  * Final wrapup - pad to 64-byte boundary with the bit pattern
3340
4152
  * 1 0* (64-bit count of bits processed, MSB-first)
@@ -3380,6 +4192,7 @@ void lsapi_MD5Final(unsigned char digest[16], struct lsapi_MD5Context *ctx)
3380
4192
  memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
3381
4193
  }
3382
4194
 
4195
+
3383
4196
  /* The four core functions - F1 is optimized somewhat */
3384
4197
 
3385
4198
  /* #define F1(x, y, z) (x & y | ~x & z) */
@@ -3480,3 +4293,18 @@ static void lsapi_MD5Transform(uint32 buf[4], uint32 const in[16])
3480
4293
  buf[3] += d;
3481
4294
  }
3482
4295
 
4296
+
4297
+ int LSAPI_Set_Restored_Parent_Pid(int pid)
4298
+ {
4299
+ int old_ppid = s_ppid;
4300
+ s_restored_ppid = pid;
4301
+ return old_ppid;
4302
+ }
4303
+
4304
+
4305
+ int LSAPI_Inc_Req_Processed(int cnt)
4306
+ {
4307
+ return __sync_add_and_fetch(s_global_counter, cnt);
4308
+ }
4309
+
4310
+