2009年4月2日星期四

Black Hole Socket Problem

Problem:



  • 1 client 1 server, connected with non-block tcp socket. Linux 2.6.*+.

  • Client writes about 3k bytes into the socket, by calling 'write' system call.

  • 'Write' returns with correct number of bytes written to the socket.

  • Server side socket receives nothing.


Causes:



  • Client side MTU is a bit larger than the MTU on some router(s) between the 2 machine

  • ICMP message requesting package fragmentation are block somehow(maybe by firewall).

  • Client insistently sends the same package again and again.


IP package with DF flag set is not fragmentated by routers into smaller ones if package size is larger than the routers. instead, router sends back an ICMP message telling the sender to fragmentate package.

But ICMP messages are blocked somewhere.


Circumstances And Phenomenon:
In this case, MTUs on client and server are both 1500.

I dumped the network traffic with tcpdump, and we can have a close look:

Phenomenon on client:
2 packages sent. The 1st package was resent time by time:


17:23:06.933574 IP (tos 0x0, ttl 64, id 57558, offset 0, flags [DF], proto: TCP (6), length: 1500) 10.54.40.43.43145 > 10.29.14.74.http: ., cksum 0x5096 (incorrect (-> 0x5c4e), 0:1448(1448) ack 1 win 46

17:23:06.933580 IP (tos 0x0, ttl 64, id 57559, offset 0, flags [DF], proto: TCP (6), length: 730) 10.54.40.43.43145 > 10.29.14.74.http: P, cksum 0x4d94 (incorrect (-> 0x3933), 1448:2126(678) ack 1 win 46

17:23:07.167049 IP (tos 0x0, ttl 64, id 57560, offset 0, flags [DF], proto: TCP (6), length: 1500) 10.54.40.43.43145 > 10.29.14.74.http: ., cksum 0x5096 (incorrect (-> 0x5b5b), 0:1448(1448) ack 1 win 46

17:23:07.634922 IP (tos 0x0, ttl 64, id 57561, offset 0, flags [DF], proto: TCP (6), length: 1500) 10.54.40.43.43145 > 10.29.14.74.http: ., cksum 0x5096 (incorrect (-> 0x5987), 0:1448(1448) ack 1 win 46



Phenomenon on server:
only the second package of size 730 received successfuly

17:23:08.605622 IP (tos 0x0, ttl 59, id 57559, offset 0, flags [DF], proto: TCP (6), length: 730) 202.108.3.204.43145 > 10.29.14.74.http: P, cksum 0x9d5b (correct), 1448:2126(678) ack 1 win 46


Solution:
As you may not have the privilege to telnet onto the router to take some adjustment, the simplest way is to change configuration on client in one of the following way:

At network level:
Decrease mtu on network adapter:


ifconfig eth* mtu 1400

At system level:
Clear the default 'MTU discovery' flag with sysctl:


net.ipv4.ip_no_pmtu_disc = 1

At user application level:
Set socket option 'IP_MTU_DISCOVER' with setsockopt(2) to clear 'DF' flag of IP package.


Reference:




  1. DF flag of IP package Header

  2. Internet Control Message Protocol

  3. IP fragmentation

  4. MTU or Maximum transmission unit

  5. IP programming

  6. Path MTU Discovery

  7. sysctl


2009年3月22日星期日

Working flow of Nginx startup phase

A big picture described nginx startup working flow from 'main' invoked to event-loop started.

For people who had written one or more nginx modules and wanna digg a bit more to see what happens while nginx starts up.

Althrough not any piece of detail nginx does is shown here, I hope this image may help if you are tired searching something through source codes tree.

This image might be a bit larger than your screen I think : |...


2008年12月9日星期二

Snippet : string number increment(done with macro)

#include
#include
#include


#define strincr(s,l) ({int i = l - 1; for(;i>=0 && (s)[i] == '9';(s)[i--] = '0'); (i>= 0) && (++(s)[i]); s;})

char a[4] = "999";

int main(int argv, char **args){

char *s = strincr(a, strlen(a));

strincr(s, strlen(s));

printf("%s", s);
return 0;
}


Just for fun, that might not be faster than by the regular way of using 'atoi'

2008年7月21日星期一

To Change USB Disk Label in Linux

RenameUSBDrive - Community Ubuntu Documentation
There are 6 programs used to label a partition - the program used depends on the partition's filesystem type:

*

For FAT16 and FAT32 partitions, use mtools.
*

For NTFS partitions, use ntfsprogs.
*

For ext2 or ext3 partitions, use e2label.
*

For JFS partitions, use jfs_tune.
*

For ReiserFS (v3) partitions, use reiserfstune.
*

For XFS partitions, use xfs_admin

2008年3月8日星期六

performance camparison between php4 and php5

zz from sourceLib

The hardware used was a 2 CPU server, where each CPU was a Intel Xeon 2.8Ghz processor.

The machine contained 2Gig of RAM(DDR2 PC3200 ECC REG 400). The hard drives on the machine were 2-40Gig SATA.

The server was running Red Hat Enterprise Linux version 3.2 with the kernel version 2.4.21-27 and the x86_64 architecture.

The version of Apache running on the machine was 1.3.33.

Each version of PHP was built with the following configuration settings:

With mysql
With ftp enabled
With pcntl (process control) enabled
With memory limit enabled
With cgi disabled

The default php.ini was used as well.


Test PHP4 PHP5 Net
test_arithmetic 0.065 0.063 3.54%
test_array_operators 0.059 0.058 1.85%
test_bitwise 0.029 0.025 13.19%
test_casting 0.186 0.176 5.63%
test_chr_fixed 0.342 0.336 1.87%
test_chr_hardcoded 0.191 0.181 4.83%
test_chr_var 0.364 0.358 1.68%
test_comment_loop 0.079 0.070 11.50%
test_compare 0.054 0.049 9.98%
test_compare_false 0.008 0.008 0.00%
test_compare_invert 0.005 0.004 8.89%
test_compare_strict 0.014 0.012 18.88%
test_compare_unstrict 0.017 0.014 18.13%
test_constants 0.039 0.039 -2.34%
test_crc32 0.016 0.017 -4.43%
test_do_while 0.390 0.353 9.54%
test_do_while_break 0.056 0.048 14.70%
test_empty 0.004 0.004 13.95%
test_empty_loop 0.078 0.070 10.65%
test_ereg 1.000 1.017 -1.63%
test_foreach 1.240 1.120 9.68%
test_get_class 0.017 0.017 1.15%
test_global_scalar_assign 0.085 0.071 16.17%
test_global_string_assign 0.140 0.129 7.85%
test_if_constant 0.010 0.010 0.00%
test_increment 0.043 0.041 5.07%
test_is_array 0.009 0.008 5.88%
test_is_object 0.008 0.008 2.38%
test_is_type 0.029 0.027 8.16%
test_isset 0.005 0.004 18.37%
test_line 0.009 0.008 2.35%
test_local_array_assign 0.187 0.176 5.73%
test_local_boolean_assign 0.074 0.073 0.41%
test_local_float_assign 0.048 0.044 8.88%
test_local_hash_assign 0.040 0.038 5.28%
test_local_integer_assign 0.048 0.044 7.92%
test_local_object_assign 0.028 0.023 20.49%
test_local_scalar_assign 0.086 0.074 13.08%
test_local_string_assign 0.123 0.114 7.25%
test_md5 0.078 0.077 1.79%
test_microtime 0.075 0.087 -15.65%
test_mt_rand 0.011 0.011 0.00%
test_ord 1.447 1.416 2.17%
test_ordered_functions 0.629 0.602 4.18%
test_ordered_functions_references 0.603 0.576 4.56%
test_preg_match 0.050 0.065 -29.37%
test_rand 0.011 0.011 -0.94%
test_references 0.017 0.015 12.21%
test_sha1 0.094 0.099 -5.98%
test_string_append 0.091 0.083 8.88%
test_strlen 0.009 0.009 -2.22%
test_switch 0.190 0.191 -0.37%
test_time 0.023 0.023 -1.31%
test_unordered_functions 0.715 0.663 7.35%
test_variable_variables 0.038 0.034 10.90%
test_while 0.423 0.358 15.49%

LAMP starts

First it is ftp. That is always the way one deploy a site to server.

Download vsftp, ./configure and then make install.
Or install with yum or atp.
Edit /etc/vsftpd.conf(or maybe /etc/vsftpd/vsftpd.conf).
To enable anonymous access, add the 2 following line:

anon_root=/data
anon_upload_enable=YES

To add another user,

todo here...

Then we go with mysql 5.0(5.0.51a.)

Get mysql noninstall version, unpack it into /usr/local.
make a symbol link as /usr/local/mysql to /usr/local/mysql.real.path.
and execute the following command to create users and start mysql daemon:

shell> groupadd mysql
shell> useradd -g mysql mysql
shell> cd /usr/local
shell> gunzip < /PATH/TO/MYSQL-VERSION-OS.tar.gz | tar xvf - shell> ln -s FULL-PATH-TO-MYSQL-VERSION-OS mysql
shell> cd mysql
shell> chown -R mysql .
shell> chgrp -R mysql .
shell> scripts/mysql_install_db --user=mysql
shell> chown -R root .
shell> chown -R mysql data
shell> bin/mysqld_safe --user=mysql &

copy one of the support-files/my-*.cnf to /etc/my.cnf as the default mysql config.

To stop mysql : mysqladmin shutdown

If needed, use mysqladmin -u root -p shutdown


After mysql started, we need to add some account to it.

mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@'localhost'
-> IDENTIFIED BY 'some_pass' WITH GRANT OPTION;

mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@'%'
-> IDENTIFIED BY 'some_pass' WITH GRANT OPTION;

mysql> GRANT RELOAD,PROCESS ON *.* TO 'admin'@'localhost';

mysql> GRANT USAGE ON *.* TO 'dummy'@'localhost';

'all privileges' means this user can do anything.
*.* means all tables
'monty' is the user name, 'localhost' is the ip address from where this user can login.
'some_pass' is password.
'grant option' means this user can do grant operation.

To use old passward format for old mysql client :

mysql> SET PASSWORD FOR
-> 'some_user'@'some_host' = OLD_PASSWORD('newpwd');

Alternative :

mysql> UPDATE mysql.user SET Password = OLD_PASSWORD('newpwd')
-> WHERE Host = 'some_host' AND User = 'some_user';
mysql> FLUSH PRIVILEGES; 
Or:
Start mysqld with the --old-passwords option.

Then we go with php5 (mysql 4.1 or later requires php 5).

download php source &

./configure --with-mysql & make install.



2008年2月28日星期四

Where's it in iphone

in iphone 1.1.3:
addressbook : /var/mobile/Library/AddressBook