首页 | 邮件资讯 | 技术教程 | 解决方案 | 产品评测 | 邮件人才 | 邮件博客 | 邮件系统论坛 | 软件下载 | 邮件周刊 | 热点专题 | 工具
网络技术 | 操作系统 | 邮件系统 | 客户端 | 电子邮箱 | 反垃圾邮件 | 邮件安全 | 邮件营销 | 移动电邮 | 邮件软件下载 | 电子书下载

产品评测

邮件安全产品评测 | 电子邮箱评测 | 邮件客户端评测 | 邮件系统评测 | 反垃圾邮件评测 |
首页 > 产品评测 > 邮件系统评测 > SMTP压力测试工具:客户端程序smtp-client.c > 正文

SMTP压力测试工具:客户端程序smtp-client.c

出处:www.mailer.com.cn 作者:www.mailer.com.cn 时间:2003-12-19 10:25:00
SMTP压力测试工具:客户端程序smtp-client.c

/*++
/* NAME
/*	smtp-sink 8
/* SUMMARY
/*	multi-threaded SMTP/LMTP test server
/* SYNOPSIS
/*	smtp-sink [-cLpv] [-w delay] [host]:port backlog
/* DESCRIPTION
/*	\\\\fIsmtp-sink\\\\fR listens on the named host (or address) and port.
/*	It takes SMTP messages from the network and throws them away.
/*	The purpose is to measure SMTP client performance, not protocol
/*	compliance.
/*	This program is the complement of the \\\\fIsmtp-source\\\\fR program.
/* .IP -c
/*	Display a running counter that is updated whenever an SMTP
/*	QUIT command is executed.
/* .IP -L
/*	Speak LMTP rather than SMTP.
/* .IP -p
/*	Disable ESMTP command pipelining.
/* .IP -v
/*	Show the SMTP conversations.
/* .IP \\\"-w delay\\\"
/*	Wait \\\\fIdelay\\\\fR seconds before responding to a DATA command.
/* SEE ALSO
/*	smtp-source, SMTP/LMTP test message generator
/* LICENSE
/* .ad
/* .fi
/*	The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/*	Wietse Venema
/*	IBM T.J. Watson Research
/*	P.O. Box 704
/*	Yorktown Heights, NY 10598, USA
/*--*/

/* System library. */

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#ifdef STRCASECMP_IN_STRINGS_H
#include 
#endif

/* Utility library. */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

/* Global library. */

#include 

/* Application-specific. */

typedef struct SINK_STATE {
    VSTREAM *stream;
    int     data_state;
    int     (*read) (struct SINK_STATE *);
    int     rcpts;
} SINK_STATE;

#define ST_ANY			0
#define ST_CR			1
#define ST_CR_LF		2
#define ST_CR_LF_DOT		3
#define ST_CR_LF_DOT_CR		4
#define ST_CR_LF_DOT_CR_LF	5

static int var_tmout;
static int var_max_line_length;
static char *var_myhostname;
static VSTRING *buffer;
static int command_read(SINK_STATE *);
static int data_read(SINK_STATE *);
static void disconnect(SINK_STATE *);
static int count;
static int counter;
static int disable_pipelining;
static int fixed_delay;
static int enable_lmtp;

/* ehlo_response - respond to EHLO command */

static void ehlo_response(SINK_STATE *state)
{
    smtp_printf(state->stream, \\\"250-%s\\\", var_myhostname);
    if (!disable_pipelining)
	smtp_printf(state->stream, \\\"250-PIPELINING\\\");
    smtp_printf(state->stream, \\\"250 8BITMIME\\\");
}

/* ok_response - send 250 OK */

static void ok_response(SINK_STATE *state)
{
    smtp_printf(state->stream, \\\"250 Ok\\\");
}

/* mail_response - reset recipient count, send 250 OK */

static void mail_response(SINK_STATE *state)
{
    state->rcpts = 0;
    ok_response(state);
}

/* rcpt_response - bump recipient count, send 250 OK */

static void rcpt_response(SINK_STATE *state)
{
    state->rcpts++;
    ok_response(state);
}

/* data_response - respond to DATA command */

static void data_response(SINK_STATE *state)
{
    state->data_state = ST_CR_LF;
    smtp_printf(state->stream, \\\"354 End data with .\\\");
    state->read = data_read;
}

/* data_event - delayed response to DATA command */

static void data_event(int unused_event, char *context)
{
    SINK_STATE *state = (SINK_STATE *) context;

    data_response(state);
}

/* dot_response - response to . command */

static void dot_response(SINK_STATE *state)
{
    if (enable_lmtp) {
	while (state->rcpts-- > 0)	/* XXX this could block */
	    ok_response(state);
    } else {
	ok_response(state);
    }
}

/* quit_response - respond to QUIT command */

static void quit_response(SINK_STATE *state)
{
    smtp_printf(state->stream, \\\"221 Bye\\\");
    if (count) {
	counter++;
	vstream_printf(\\\"%d\\\\r\\\", counter);
	vstream_fflush(VSTREAM_OUT);
    }
}

/* data_read - read data from socket */

static int data_read(SINK_STATE *state)
{
    int     ch;
    struct data_trans {
	int     state;
	int     want;
	int     next_state;
    };
    static struct data_trans data_trans[] = {
	ST_ANY, \\\'\\\\r\\\', ST_CR,
	ST_CR, \\\'\\\\n\\\', ST_CR_LF,
	ST_CR_LF, \\\'.\\\', ST_CR_LF_DOT,
	ST_CR_LF_DOT, \\\'\\\\r\\\', ST_CR_LF_DOT_CR,
	ST_CR_LF_DOT_CR, \\\'\\\\n\\\', ST_CR_LF_DOT_CR_LF,
    };
    struct data_trans *dp;

    /*
     * We must avoid blocking I/O, so get out of here as soon as both the
     * VSTREAM and kernel read buffers dry up.
     */
    while (vstream_peek(state->stream) > 0
	   || peekfd(vstream_fileno(state->stream)) > 0) {
	if ((ch = VSTREAM_GETC(state->stream)) == VSTREAM_EOF)
	    return (-1);
	for (dp = data_trans; dp->state != state->data_state; dp++)
	     /* void */ ;

	/*
	 * Try to match the current character desired by the state machine.
	 * If that fails, try to restart the machine with a match for its
	 * first state.  This covers the case of a CR/LF/CR/LF sequence
	 * (empty line) right before the end of the message data.
	 */
	if (ch == dp->want)
	    state->data_state = dp->next_state;
	else if (ch == data_trans[0].want)
	    state->data_state = data_trans[0].next_state;
	else
	    state->data_state = ST_ANY;
	if (state->data_state == ST_CR_LF_DOT_CR_LF) {
	    if (msg_verbose)
		msg_info(\\\".\\\");
	    dot_response(state);
	    state->read = command_read;
	    break;
	}
    }
    return (0);
}

 /*
  * The table of all SMTP commands that we can handle.
  */
typedef struct SINK_COMMAND {
    char   *name;
    void    (*response) (SINK_STATE *);
} SINK_COMMAND;

static SINK_COMMAND command_table[] = {
    \\\"helo\\\", ok_response,
    \\\"ehlo\\\", ehlo_response,
    \\\"lhlo\\\", ehlo_response,
    \\\"mail\\\", mail_response,
    \\\"rcpt\\\", rcpt_response,
    \\\"data\\\", data_response,
    \\\"rset\\\", ok_response,
    \\\"noop\\\", ok_response,
    \\\"vrfy\\\", ok_response,
    \\\"quit\\\", quit_response,
    0,
};

/* command_read - talk the SMTP protocol, server side */

static int command_read(SINK_STATE *state)
{
    char   *command;
    SINK_COMMAND *cmdp;

    smtp_get(buffer, state->stream, var_max_line_length);
    if ((command = strtok(vstring_str(buffer), \\\" \\\\t\\\")) == 0) {
	smtp_printf(state->stream, \\\"500 Error: unknown command\\\");
	return (0);
    }
    if (msg_verbose)
	msg_info(\\\"%s\\\", command);
    for (cmdp = command_table; cmdp->name != 0; cmdp++)
	if (strcasecmp(command, cmdp->name) == 0)
	    break;
    if (cmdp->name == 0) {
	smtp_printf(state->stream, \\\"500 Error: unknown command\\\");
	return (0);
    }
    if (cmdp->response == data_response && fixed_delay > 0) {
	event_request_timer(data_event, (char *) state, fixed_delay);
    } else {
	cmdp->response(state);
	if (cmdp->response == quit_response)
	    return (-1);
    }
    return (0);
}

/* read_event - handle command or data read events */

static void read_event(int unused_event, char *context)
{
    SINK_STATE *state = (SINK_STATE *) context;

    do {
	switch (vstream_setjmp(state->stream)) {

	default:
	    msg_panic(\\\"unknown error reading input\\\");

	case SMTP_ERR_TIME:
	    msg_panic(\\\"attempt to read non-readable socket\\\");
	    /* NOTREACHED */

	case SMTP_ERR_EOF:
	    msg_warn(\\\"lost connection\\\");
	    disconnect(state);
	    return;

	case 0:
	    if (state->read(state) < 0) {
		if (msg_verbose)
		    msg_info(\\\"disconnect\\\");
		disconnect(state);
		return;
	    }
	}
    } while (vstream_peek(state->stream) > 0);
}

/* disconnect - handle disconnection events */

static void disconnect(SINK_STATE *state)
{
    event_disable_readwrite(vstream_fileno(state->stream));
    vstream_fclose(state->stream);
    myfree((char *) state);
}

/* connect_event - handle connection events */

static void connect_event(int unused_event, char *context)
{
    int     sock = (int) context;
    SINK_STATE *state;
    int     fd;

    if ((fd = accept(sock, (struct sockaddr *) 0, (SOCKADDR_SIZE *) 0)) >= 0) {
	if (msg_verbose)
	    msg_info(\\\"connect\\\");
	non_blocking(fd, NON_BLOCKING);
	state = (SINK_STATE *) mymalloc(sizeof(*state));
	state->stream = vstream_fdopen(fd, O_RDWR);
	state->read = command_read;
	state->data_state = 0;
	smtp_timeout_setup(state->stream, var_tmout);
	smtp_printf(state->stream, \\\"220 %s ESMTP\\\", var_myhostname);
	event_enable_read(fd, read_event, (char *) state);
    }
}

/* usage - explain */

static void usage(char *myname)
{
    msg_fatal(\\\"usage: %s [-cLpv] [host]:port backlog\\\", myname);
}

int     main(int argc, char **argv)
{
    int     sock;
    int     backlog;
    int     ch;

    /*
     * Initialize diagnostics.
     */
    msg_vstream_init(argv[0], VSTREAM_ERR);

    /*
     * Parse JCL.
     */
    while ((ch = GETOPT(argc, argv, \\\"cLpvw:\\\")) > 0) {
	switch (ch) {
	case \\\'c\\\':
	    count++;
	    break;
	case \\\'L\\\':
	    enable_lmtp = 1;
	    break;
	case \\\'p\\\':
	    disable_pipelining = 1;
	    break;
	case \\\'v\\\':
	    msg_verbose++;
	    break;
	case \\\'w\\\':
	    if ((fixed_delay = atoi(optarg)) <= 0)
		usage(argv[0]);
	    break;
	default:
	    usage(argv[0]);
	}
    }
    if (argc - optind != 2)
	usage(argv[0]);
    if ((backlog = atoi(argv[optind + 1])) <= 0)
	usage(argv[0]);

    /*
     * Initialize.
     */
    buffer = vstring_alloc(1024);
    var_myhostname = \\\"smtp-sink\\\";
    sock = inet_listen(argv[optind], backlog, BLOCKING);

    /*
     * Start the event handler.
     */
    event_enable_read(sock, connect_event, (char *) sock);
    for (;;)
	event_loop(-1);
}
相关文章 热门文章
  • 企业邮件系统—全景扫描
  • 邮件服务器性能测试浅析
  • 选择邮件服务器十二要素
  • 邮件系统应用—聚焦企业级市场
  • Windows下的邮件服务器性能评测
  • SMTP压力测试工具:客户端程序smtp-client.c
  • 企业邮件系统特点
  • 典型邮件服务器详解
  • 手记:体验Exchange 2007的共享日历服务
  • 高效安全 企业邮件服务器软件横评
  • 网上“邮局” 任我行
  • E-mail服务器应用方案比较测试报告
  • 自由广告区
     
    最新软件下载
  • SharePoint Server 2010 部署文档
  • Exchange 2010 RTM升级至SP1 教程
  • Exchange 2010 OWA下RBAC实现的组功能...
  • Lync Server 2010 Standard Edition 标..
  • Lync Server 2010 Enterprise Edition...
  • Forefront Endpoint Protection 2010 ...
  • Lync Server 2010 Edge 服务器部署文档
  • 《Exchange 2003专家指南》
  • Mastering Hyper-V Deployment
  • Windows Server 2008 R2 Hyper-V
  • Microsoft Lync Server 2010 Unleashed
  • Windows Server 2008 R2 Unleashed
  • 今日邮件技术文章
  • 腾讯,在创新中演绎互联网“进化论”
  • 华科人 张小龙 (中国第二代程序员 QQ...
  • 微软推出新功能 提高Hotmail密码安全性
  • 快压技巧分享:秒传邮件超大附件
  • 不容忽视的邮件营销数据分析过程中的算..
  • 国内手机邮箱的现状与未来发展——访尚..
  • 易观数据:2011Q2中国手机邮箱市场收入..
  • 穿越时空的爱恋 QQ邮箱音视频及贺卡邮件
  • Hotmail新功能:“我的朋友可能被黑了”
  • 入侵邻居网络发骚扰邮件 美国男子被重..
  • 网易邮箱莫子睿:《非你莫属》招聘多过..
  • 中国电信推广189邮箱绿色账单
  • 最新专题
  • 鸟哥的Linux私房菜之Mail服务器
  • Exchange Server 2010技术专题
  • Windows 7 技术专题
  • Sendmail 邮件系统配置
  • 组建Exchange 2003邮件系统
  • Windows Server 2008 专题
  • ORF 反垃圾邮件系统
  • Exchange Server 2007 专题
  • ISA Server 2006 教程专题
  • Windows Vista 技术专题
  • “黑莓”(BlackBerry)专题
  • Apache James 专题
  • 分类导航
    邮件新闻资讯:
    IT业界 | 邮件服务器 | 邮件趣闻 | 移动电邮
    电子邮箱 | 反垃圾邮件|邮件客户端|网络安全
    行业数据 | 邮件人物 | 网站公告 | 行业法规
    网络技术:
    邮件原理 | 网络协议 | 网络管理 | 传输介质
    线路接入 | 路由接口 | 邮件存储 | 华为3Com
    CISCO技术 | 网络与服务器硬件
    操作系统:
    Windows 9X | Linux&Uinx | Windows NT
    Windows Vista | FreeBSD | 其它操作系统
    邮件服务器:
    程序与开发 | Exchange | Qmail | Postfix
    Sendmail | MDaemon | Domino | Foxmail
    KerioMail | JavaMail | Winwebmail |James
    Merak&VisNetic | CMailServer | WinMail
    金笛邮件系统 | 其它 |
    反垃圾邮件:
    综述| 客户端反垃圾邮件|服务器端反垃圾邮件
    邮件客户端软件:
    Outlook | Foxmail | DreamMail| KooMail
    The bat | 雷鸟 | Eudora |Becky! |Pegasus
    IncrediMail |其它
    电子邮箱: 个人邮箱 | 企业邮箱 |Gmail
    移动电子邮件:服务器 | 客户端 | 技术前沿
    邮件网络安全:
    软件漏洞 | 安全知识 | 病毒公告 |防火墙
    攻防技术 | 病毒查杀| ISA | 数字签名
    邮件营销:
    Email营销 | 网络营销 | 营销技巧 |营销案例
    邮件人才:招聘 | 职场 | 培训 | 指南 | 职场
    解决方案:
    邮件系统|反垃圾邮件 |安全 |移动电邮 |招标
    产品评测:
    邮件系统 |反垃圾邮件 |邮箱 |安全 |客户端
    广告联系 | 合作联系 | 关于我们 | 联系我们 | 繁體中文
    版权所有:邮件技术资讯网©2003-2010 www.5dmail.net, All Rights Reserved
    www.5Dmail.net Web Team   粤ICP备05009143号