Vomit: The memcached server does not take over the set command from nc!

Source: Internet
Author: User

Address: http://blog.csdn.net/ffb/article/details/17437101

When using nc to access the memcache service, it is found that the set command always fails, but other commands are available. For telnet, everything is normal, and it is suspected of a server bug. It is worth studying.

The nc command is:

nc 127.0.0.1 11212
The telnet command is as follows:
telnet 127.0.0.1 11212
So I tried to use wireshark to capture packets and analyze the data difference,

Telnet request data is as follows:

0000   73 65 74 20 70 79 77 20 31 20 30 20 33 0d 0a 31  set pyw 1 0 3..10010   30 30 0d 0a                                      00..

The request data of nc is as follows:

0000   73 65 74 20 70 79 77 20 31 20 30 20 33 0a        set pyw 1 0 3.0000   31 30 30 0a                                      100.

It is found that the return letter sent by nc is 0A, And the return letter sent by telnet is 0D 0A, which should be caused by this difference, but other commands sent by nc can be correctly executed, we suspect that the server code has bugs.

View the source code and process the code in the Command Format in:

Memcached. c: try_read_command

2455     cont = el + 1;                                                                                           2456     if ((el - c->rcurr) > 1 && *(el - 1) == '\r') {                                                          2457         el--;                                                                                                2458     }                                                                                                        2459     *el = '\0';

Here, el is

2433     el = memchr(c->rcurr, '\n', c->rbytes);

It seems that the code is okay. As a result, the reading command and judgment position are in drive_machine (), where c-> state is used to control the processing flow, so you only need to track the changes to this variable. So tracking:

$ gdb ./memcached(gdb) set args -A 11212(gdb) b try_read_commandBreakpoint 1 at 0x409e79: file memcached.c, line 2422.(gdb) r

Client Input

get pywENDset pyw 0 0 3100
It can be seen that for the set command from ns, after try_read_command, the status value changes to conn_nread rather than conn_mwrite, meaning that the command parameters need to be read again. Therefore, the conn_nread breakpoint is added.

(Gdb) B 2848

After debugging, you can see this Code:

2848             if (c->rlbytes == 0) {                                                                           2849                 complete_nread(c);                                                                                                          2850                 break;                                                                                       2851             }
When I followed in, I found very suspicious code:
948     if (strncmp(ITEM_data(it) + it->nbytes - 2, "\r\n", 2) != 0) {

Change

948     if (strncmp(ITEM_data(it) + it->nbytes - 2, "\r\n", 2) != 0 && strncmp(ITEM_data(it) + it->nbytes - 1, "\n", 1) != 0) {
Compile and run the command, re-execute the preceding command, and press enter once to find that the data is successfully saved.

Why do we need to press enter once? The reason is that the entire state flow on the memcache server is driven by the number of bytes that have been read. When you enter the set command, the process_update_command function sets a number of expected bytes to the variable conn: rlbytes. The expected value is calculated by \ r \ n by default. For example, if you want to input three more bytes, this value is set to 5.

Since the processing methods in the Code are highly bound to \ r \ n, such as item_make_header (), if you want to completely solve this problem, it is best to analyze the carriage return type of the terminal after the first command, unified identification, and improves the compatibility of related codes based on the identification. However, due to the many modifications involved, this study is now available.

Before the end, I changed my mind. The problem involved here is that the memcache Communication Protocol stipulates that \ r \ n is the standard command end method, so the server code does not need to be modified, as long as the client sends \ r \ n as the carriage return according to the Protocol requirements (check whether it can comply with the requirements before changing), man ran the nc and tried the following command:

$ nc -C 127.0.0.1 11211set pyw 1 0 3100STORED
OK. Solve the problem.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.