Postfix网络编程的结构:
Tcp/Ip连接:inet_connect.c inet_listern.c
//src/util/inet_connect.c
/* inet_connect - connect to TCP listener */
int inet_connect(const char *addr, int block_mode, int timeout);
Postifx 自身封装了地址结构,端口号的信息,
struct addrinfo *res;
struct addrinfo *res0;
int aierr;
int sock;
MAI_HOSTADDR_STR hostaddr;
INET_PROTO_INFO *proto_info;
int found;
先将字符串装换为主机名称和端口号,并释放字符串,再将其转换为sockaddr,程序中有许多safety 或者sanity check
/*
* Safety net.
*/
if (strchr((char *) proto_info->sa_family_list, res->ai_family) == 0) {
msg_info("skipping address family %d for host %s",
res->ai_family, host);
continue;
}
----进行sock连接:
if ((sock = inet_connect_one(res, block_mode, timeout)) < 0) {
if (msg_verbose)
msg_info("%m");
} else
break;
}
static int inet_connect_one(struct addrinfo * res, int block_mode, int timeout);
调用set_inet_windowsize设置发送和接收的缓冲区大小,定义了 inet_windowsize 设置这一个大小。
调用timed_connect 设置deadline。
if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void *) &windowsize,
sizeof(windowsize)) < 0)
msg_warn("setsockopt SO_SNDBUF %d: %m", windowsize);
if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *) &windowsize,
sizeof(windowsize)) < 0)
msg_warn("setsockopt SO_RCVBUF %d: %m", windowsize);
Unix 域连接:Unix_connect.c unix_listern.c
触发式客户端:inet_trigger.c、unix_trigger.c、fifo_trigger.c
int inet_trigger(const char *service, const char *buf, ssize_t len, int timeout);
----通过inet_connect进行连接。
/*
* Connect...
*/
if ((fd = inet_connect(service, BLOCKING, timeout)) < 0) {
if (msg_verbose)
msg_warn("%s: connect to %s: %m", myname, service);
return (-1);
}
close_on_exec(fd, CLOSE_ON_EXEC);
ip = (struct inet_trigger *) mymalloc(sizeof(*ip));
ip->fd = fd;
ip->service = mystrdup(service);
/*
* Write the request...
*/
if (write_buf(fd, buf, len, timeout) < 0
|| write_buf(fd, "", 1, timeout) < 0)
if (msg_verbose)
msg_warn("%s: write to %s: %m", myname, service);
安排一个时间事件,在此时间事件inet_trigger_event中执行close。即不进行“会话”,在一个限定时间内关闭连接。每隔一段时间执行event_loop,执行其中的事件。
/*
* Wakeup when the peer disconnects, or when we lose patience.
*/
if (timeout > 0)
event_request_timer(inet_trigger_event, (void *) ip, timeout + 100);
event_enable_read(fd, inet_trigger_event, (void *) ip);
return (0);