5.6.7 执行指令状态机
来源:互联网 发布:网络视频电话机 编辑:程序博客网 时间:2024/06/08 11:49
经过了以上的准备工作,从4973行开始正式进入指令循环(状态机)工作。
首先要进行一些前置操作:
1 smtpd_hard_error_limit限制判断与处理。
2 如果开启smtputf8支持,判断state->buffer是否满足utf8格式。
3 非规范命令处理。
4 将会话信息按单词读取到SMTPD_TOKEN结构体。
5 smtpd_noop_commands参数处理。
/smtpd/smtpd.c49694970 /*4971 * The command read/execute loop.4972 */4973 for (;;) {4974 if (state->flags &SMTPD_FLAG_HANGUP)4975 break;4976 if (state->error_count >=var_smtpd_hard_erlim) {4977 state->reason =REASON_ERROR_LIMIT;4978 state->error_mask |=MAIL_ERROR_PROTOCOL;4979 smtpd_chat_reply(state,"421 4.7.0 %s Error: too many errors",4980 var_myhostname);4981 break;4982 }
4976-4982 smtpd_hard_error_limit限制判断与处理
4969-4982在3.8.2节我们已经介绍了smtpd_soft_error_limit和smtpd_hard_error_limit参数的作用。目前为止我们一直间接的通过smtpd_chat_replay判断state->error_count是否超过了smtpd_soft_error_limit限制。现在我们已经开始进入指令循环了,要在此之前要和恶意客户端做结算,进行smtpd_hard_error_limit限制判断,不与恶意客户端进行会话。
4983 watchdog_pat();4984 smtpd_chat_query(state);
4984 从客户端读取行,开启协议解析旅程。
4985 /* Safety: protect internalinterfaces against malformed UTF-8. */4986 if (var_smtputf8_enable &&valid_utf8_string(STR(state->buffer),4987 LEN(state->buffer)) == 0) {4988 state->error_mask |=MAIL_ERROR_PROTOCOL;4989 smtpd_chat_reply(state,"500 5.5.2 Error: bad UTF-8 syntax");4990 state->error_count++;4991 continue;4992 }
如果开启smtputf8支持,判断state->buffer是否满足utf8格式
4986-4992 var_smtputf8_enable即参数smtputf8_enable,这是postfix3.0新增功能。当smtputf8_enable值为yes时,postfix可以接收utf-8格式的收发件人域名。这里我们先判断一下如果smtputf8_enable开启时,state->buffer会话内容是否是正确的utf8编码。
4993 /* Move into smtpd_chat_query()and update session transcript. */4994 if (smtpd_cmd_filter != 0) {4995 for (cp =STR(state->buffer); *cp && IS_SPACE_TAB(*cp); cp++)4996 /* void */ ;4997 if ((cp =dict_get(smtpd_cmd_filter, cp)) != 0) {4998 msg_info("%s:replacing command \"%.100s\" with \"%.100s\"",4999 state->namaddr,STR(state->buffer), cp);5000 vstring_strcpy(state->buffer, cp);5001 } else if(smtpd_cmd_filter->error != 0) {5002 msg_warn("%s:%slookup error for \"%.100s\"",5003 smtpd_cmd_filter->type,smtpd_cmd_filter->name,5004 printable(STR(state->buffer), '?'));5005 vstream_longjmp(state->client, SMTP_ERR_DATA);5006 }5007 }
非规范命令处理
4993-5007
postfix2.7中加入的smtpd_command_filter参数用来设置一个字典表,记录对于客户端收到的不规范而postfix又不想放弃处理的smtp会话请求。示例如下:
/etc/postfix/main.cf:
smtpd_command_filter = pcre:/etc/postfix/command_filter
# Work around clients that send empty lines.
/^\s*$/ NOOP
这里我们将客户端发送的空行视为smtp NOOP指令
smtpd_cmd_filter即为保存字典表信息的DICT结构体,在pre_jail_init函数中被初始化
if (*var_smtpd_cmd_filter) smtpd_cmd_filter= dict_open(var_smtpd_cmd_filter, O_RDONLY, DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX);
var_smtpd_cmd_filter即参数smtpd_command_filter
这里我们搜索smtpd_cmd_filter,如果客户端请求在表中,则将state->buffer命令信息设置为字典文件中相应的规范值。因为我们在smtpd_cmd_talbe[]数组(见5.1.3节)中存放的都是规范命令,所以我们首先看一下是否有需要处理的不规范命令,否则如果先进行指令循环,则这些客户端发来的信息将被视为错误。
5008 if ((argc = smtpd_token(vstring_str(state->buffer),&argv)) == 0) {5009 state->error_mask |=MAIL_ERROR_PROTOCOL;5010 smtpd_chat_reply(state,"500 5.5.2 Error: bad syntax");5011 state->error_count++;5012 continue;5013 }
将会话信息按单词读取到SMTPD_TOKEN结构体。
5008-5013 我们用smtpd_token函数将从客户端得到的字符串转化为SMTPD_TOKEN结构体,该结构体将会话内容保存为字符串数组。
typedef struct SMTPD_TOKEN { int tokval; char *strval; VSTRING *vstrval;} SMTPD_TOKEN;
我们看一下单元测试的结果(见图5-5):
图5-5 smtpd_token函数测试结果
smtpd_token函数将mailfrom:zhangsan@163.com读成3个字符串,类型为other
SMTPD_TOKEN共有3个类型:
#define SMTPD_TOK_OTHER 0
#define SMTPD_TOK_ADDR 1
#define SMTPD_TOK_ERROR 2
5014 /* Ignore smtpd_noop_cmds lookuperrors. Non-critical feature. */5015 if (*var_smtpd_noop_cmds5016 &&string_list_match(smtpd_noop_cmds, argv[0].strval)) {5017 smtpd_chat_reply(state,"250 2.0.0 Ok");5018 if (state->junk_cmds++ >var_smtpd_junk_cmd_limit)5019 state->error_count++;5020 continue;5021 }
smtpd_noop_commands参数处理
5014-5021 smtpd_noop_commands参数表示对于该参数指定的smtp命令,服务器直接返回250成功码。
- 5.6.7 执行指令状态机
- RPC状态机执行过程
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- RadioGroup+Fragment
- C++ 快速排序实现
- try catch 捕获异常
- CTS Verifier test
- Android动画--Interpolator(插值器)
- 5.6.7 执行指令状态机
- TextView 使用Selector设置颜色
- 音频相关的一些名词解释
- 什么是GPU,GPU怎么工作的,什么是图形的渲染,渲染怎么完成的。
- 项目——作物环境检测采集站
- 前端构建工具gulpjs的使用介绍及技巧
- java学习笔记-运算符
- cassandra 记录
- java重载的意义