为了实现在Openssl内部对象结构和标准的DER编码对象之间格式的转换,OpenSSL定义了一组完成该功能的函数,这些函数基本上是以i2d(内部->DER)和d2i(DER->内部)开头的。跟其他各个系列的函数一样。

TYPE *d2i_TYPE(TYPE a, unsigned char pp, long length);
int i2d_TYPE(TYPE a, unsigned char pp);

DESCRIPTION

TYPE is used a placeholder for any of the OpenSSL datatypes, such as X509_CRL.

These functions convert OpenSSL objects to and from their ASN.1/DER encoding. Unlike the C structures which can have pointers to sub-objects within, the DER is a serialized encoding, suitable for sending over the network, writing to a file, and so on.

d2i_TYPE() attempts to decode len bytes at in.If successful a pointer to the TYPE structure is returned and in is incremented to the byte following the parsed data. If a is not NULL then a pointer to the returned structure is also written to *a. If an error occurred then NULL is returned.

On a successful return, if a is not NULL then it is assumed that a contains a valid TYPE structure and an attempt is made to reuse it. This "reuse" capability is present for historical compatibility but its use is strongly discouraged (see BUGS below,and the discussion in the RETURN VALUES section).

i2d_TYPE() encodes the structure pointed to by a into DER format. If out is not NULL, it writes the DER encoded data to the buffer at *out, and increments it to point after the data just written. If the return value is negative an error occurred, otherwise it returns the length of the encoded data.

If out is NULL memory will be allocated for a buffer and the encoded data written to it. In this case out is not incremented and it points to the start of the data just written.

示例代码:
Allocate and encode the DER encoding of an X509 structure:

 int len;
 unsigned char *buf;

 buf = NULL;
 len = i2d_X509(x, &buf);
 if (len < 0)
     /* error */

Attempt to decode a buffer:

X509 *x;
 unsigned char *buf;
 const unsigned char *p;
 int len;

 /* Set up buf and len to point to the input buffer. */
 p = buf;
 x = d2i_X509(NULL, &p, len);
 if (x == NULL)
     /* error */

函数原型:
@brief load a character certification context into system context. If '*cert' is pointed to the
certification, then load certification into it. Or create a new X509 certification object

X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len)
{
    int m = 0;
    int ret;
    X509 *x;

    SSL_ASSERT2(buffer);
    SSL_ASSERT2(len);

    if (cert && *cert) {
        x = *cert;
    } else {
        x = X509_new();
        if (!x) {
            SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_new() return NULL");
            goto failed1;
        }
        m = 1;
    }

    ret = X509_METHOD_CALL(load, x, buffer, len);
    if (ret) {
        SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_METHOD_CALL(load) return %d", ret);
        goto failed2;
    }

    return x;

failed2:
    if (m)
        X509_free(x);
failed1:
    return NULL;
}

ASN1的基本的数据类型一般都有如下函数:new、free、i2d、d2i、i2a、a2i、print、set、get、cmp和dup。其中new、free、i2d、d2i函数通过宏定义实现。new函数用于分配空间,生成ASN1数据结构;free用于释放空间;i2d函数将ASN1数据结构转换为DER编码;d2i将DER编码转换为ASN1数据结构,i2a将内部结构转换为ASCII码,a2i将ASCII码转换为内部数据结构。set函数用于设置ASN1类型的值,get函数用于获取ASN1类型值;print将ASN1类型打印;cmp用于比较ASN1数据结构;dup函数进行数据结构的拷贝。

string ssl_printnum(ASN1_INTEGER *i)
{
    string strret;
    int len;
    char *data;
    BIO *bio = BIO_new(BIO_s_mem());  

    i2a_ASN1_INTEGER(bio, i);
    len = BIO_get_mem_data(bio, &data);
    strret.assign(data, len);
    BIO_free(bio);

    return strret;
}
string ssl_printstr(ASN1_OCTET_STRING *i)
{
    string strret;
    int len;
    char *data;
    BIO *bio = BIO_new(BIO_s_mem());  

    i2a_ASN1_STRING (bio, i, V_ASN1_OCTET_STRING);
    len = BIO_get_mem_data(bio, &data);
    strret.assign(data, len);
    BIO_free(bio);

    return strret;
}

除恒大外或仍有大开发商现流动性问题 但中国料不会很快放松楼市政策--澳新 | 路透 update:2021-9-9
除深陷困境的中国恒大以外,澳新银行最新报告认为,不排除仍有大型开发商面临流动性问题,但风险尚不会蔓延到整个行业;同时澳新预计中国的房地产调控政策不会很快松动。

澳新银行资深中国经济学家王蕊在周四发布四季度中国房地产市场展望报告,中国收紧房地产调控已导致开发建设活动急速放缓,对未来几季度增长前景构成压力。

澳新预计,四季度房地产开发投资同比增速可能降至1-2%(两年平均为5-6%),而去年同比为9.9%。而房地产对GDP增长的贡献将从之前的0.7-0.8个百分点降至0.1个百分点。

“对单个开发商而言,流动性仍是短期内的忧患,但整个行业仍不足虑。”澳新银行称,在获取银行融资难、房地产销售放缓的情况下,踩了“三道红线”的开发商风险很高。

据其统计,前30家中国开发商中有五家踩了三道红线,其中四家的现金短债比在上半年有所降低。

“除掉负债累累的中国恒大,我们不能排除还有一些大型开发商短期内也可能遭遇流动性问题。”澳新补充道,流动性不会扩散到整个行业。前30大房企上半年整体现金短债比已经从去年同期的1.18升至1.23。

澳新银行预计,一些开发商可能在四季度面临流动性挑战,央行有可能注入流动性,政府或提供援助,同时国企亦有望给高负债民企提供支持。

王蕊并指出,预计中国不会很快放松房地产政策,房地产日渐被视为加剧收入不平等的重要因素,成为实现“共同富裕”的阻碍。住建部此前表示,要用三年左右的时间,实现房地产市场秩序的明显好转。

有消息称,恒大集团计划在9月21日暂停向两家银行支付到期贷款的利息。这导致恒大股债近期接连下挫。今年迄今,恒大港股已跌去近八成。

伴随着房地产高压调控效应持续显现,中国房价7月已经全面放缓。路透访问10家机构的预估中值显示,2021年中国住宅均价同比涨幅预计为3.5%,低于三个月前上次路透季度调查的预估中值5%。

Referenced from:https://cn.reuters.com/article/china-rea-developers-liquidity-0909-idCNKBS2G50C8?il=0

澳新银行任命王蕊为资深中国经济学家 - 21财经 update:2021-9-9
2017年1月5日,澳大利亚和新西兰银行集团有限公司(简称“澳新银行”)宣布,王蕊(Betty
Wang)将加入澳新银行担任资深中国经济学家一职,王蕊将向澳新银行大中华区首席经济学家杨宇霆博士(Raymond
Yeung)汇报,常驻香港。

王蕊将主要负责研究中国宏观经济和离岸人民币市场动态。

在加入澳新银行之前,王蕊曾在渣打银行担任经济学家,负责中国和日本的经济研究。

Referenced from:https://m.21jingji.com/article/20170105/herald/d446246607200c1023c32212c71aacad.html

传恒大将推迟向银行支付本月贷款利息_-东东有鱼私募网 update:2021-9-9
9月8日(周三),据REDD引述4名知情人士称,频频传出负面消息的中国恒大通知两间银行,暂停支付9月21日到期的贷款利息,同时,恒大可能从9月8日起暂停所有对其理财产品的支付。
深陷债务危机的中国恒大又被传出新消息,REDD报道称,恒大告知其中一间银行,集团财务不会签字同意支付利息。

Referenced from:https://simu.jd.com/info/3kpez5utu4.html

linux c syslog LOG_CONS off
linux c syslog 控制台不输出

openlog("SEC", LOG_PID, LOG_USER);

使用上面的选项打开控制台就不输出日志了。

可用的参数:
option

The option argument to openlog() is an OR of any of these:
LOG_CONS
Write directly to system console if there is an error while sending to system logger.

LOG_NDELAY

Open the connection immediately (normally, the connection is opened when the first message is logged).

LOG_NOWAIT

Don't wait for child processes that may have been created while logging the message. (The GNU C library does not create a child process, so this option has no effect on Linux.)

LOG_ODELAY

The converse of LOG_NDELAY; opening of the connection is delayed until syslog() is called. (This is the default, and need not be specified.)

LOG_PERROR

(Not in POSIX.1-2001 or POSIX.1-2008.) Print to stderr as well.

LOG_PID

Include PID with each message.

linux c openlog example

Here is an example of openlog, syslog, and closelog:

This example sets the logmask so that debug and informational messages get discarded without ever reaching Syslog. So the second syslog in the example does nothing.

#include <syslog.h>

setlogmask (LOG_UPTO (LOG_NOTICE));

openlog ("exampleprog", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);

syslog (LOG_NOTICE, "Program started by User %d", getuid ());
syslog (LOG_INFO, "A tree falls in a forest");

closelog ();

rabbitmq之一概念解释(信道、交换器和路由键、队列)
update:2021-9-9

一、 channel 信道:

  概念:信道是生产消费者与rabbit通信的渠道,生产者publish或是消费者subscribe一个队列都是通过信道来通信的。信道是建立在TCP连接上的虚拟连接,什么意思呢?就是说rabbitmq在一条TCP上建立成百上千个信道来达到多个线程处理,这个TCP被多个线程共享,每个线程对应一个信道,信道在rabbit都有唯一的ID
,保证了信道私有性,对应上唯一的线程使用。

       疑问:为什么不建立多个TCP连接呢?原因是rabbit保证性能,系统为每个线程开辟一个TCP是非常消耗性能,每秒成百上千的建立销毁TCP会严重消耗系统。所以rabbitmq选择建立多个信道(建立在tcp的虚拟连接)连接到rabbit上。

     类似概念:TCP是电缆,信道就是里面的光纤,每个光纤都是独立的,互不影响。

二、exchange 交换机和绑定routing key

  exchange的作用就是类似路由器,routing key 就是路由键,服务器会根据路由键将消息从交换器路由到队列上去。

  exchange有多个种类:direct,fanout,topic,header(非路由键匹配,功能和direct类似,很少用)。前三种类似集合对应关系那样,(direct)1:1,(fanout)1:N,(topic)N:1

  direct: 1:1类似完全匹配

  fanout:1:N 
可以把一个消息并行发布到多个队列上去,简单的说就是,当多个队列绑定到fanout的交换器,那么交换器一次性拷贝多个消息分别发送到绑定的队列上,每个队列有这个消息的副本。

     ps:这个可以在业务上实现并行处理多个任务,比如,用户上传图片功能,当消息到达交换器上,它可以同时路由到积分增加队列和其它队列上,达到并行处理的目的,并且易扩展,以后有什么并行任务的时候,直接绑定到fanout交换器不需求改动之前的代码。

  topic   N:1 ,多个交换器可以路由消息到同一个队列。根据模糊匹配,比如一个队列的routing key
为*.test ,那么凡是到达交换器的消息中的routing key 后缀.test都被路由到这个队列上。

三、结合信道、交换器和路由键到队列

  总结几点重要知识:1.信道才是rabbit通信本质,生产者和消费者都是通过信道完成消息生产消费的。2.交换器本质是一张路由查询表(名称和队列id,类似于hash表),这是一个虚拟出来的东西,并不存在真实的交换器。

  消息的生命周期:生产者生产消息A
交由信道,信道通过消息(消息由载体和标签)的标签(路由键)放到交换器发送到队列上(其实就是查询匹配,一旦匹配到了规则,信道就直接和队列产生连接,然后将消息发送过去)

Referenced from:https://www.huaweicloud.com/articles/12567586.html

RabbitMQ入门:路由(Routing) update:2021-9-9
fanout类型的exchange,它是一种通过广播方式发送消息的路由器,所有和exchange建立的绑定关系的队列都会接收到消息。但是有一些场景只需要订阅到一部分消息,这个时候就不能使用fanout
类型的exchange了

Direct Exchange(直接路由器) Direct Exchange,通过Routing
Key来决定需要将消息发送到哪个或者哪些队列中。 它是一种完全按照routing key(路由关键字)进行投递的:当消息中的routing
key和队列中的binding key完全匹配时,才进行会将消息投递到该队列中。

Referenced from:https://www.cnblogs.com/sam-uncle/p/9209666.html

参照RabbitMq官网的安装教程(Installing on Debian and Ubuntu),来进行安装。

sudo apt install erlang-nox

安装完成后执行

erl

Erlang/OTP 22 [erts-10.6.4] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1]

Eshell V10.6.4 (abort with ^G)

wget -O- https://www.rabbitmq.com/rabbitmq-release-signing-key.asc | sudo apt-key add -

sudo apt update
sudo apt install rabbitmq-server

安装完成后,查看服务状态

systemctl status rabbitmq-server

● rabbitmq-server.service - RabbitMQ Messaging Server

 Loaded: loaded (/lib/systemd/system/rabbitmq-server.service; enabled; vendor preset: enabled)
 Active: active (running) since Tue 2021-09-07 09:53:48 CST; 2 days ago

Main PID: 1581436 (beam.smp)

 Status: "Initialized"
  Tasks: 235 (limit: 18732)
 Memory: 95.7M
 CGroup: /system.slice/rabbitmq-server.service
         ├─1581432 /bin/sh /usr/sbin/rabbitmq-server
         ├─1581436 /usr/lib/erlang/erts-10.6.4/bin/beam.smp -W w -A 192 -MBas ageffcbf -MHas ageffcbf -MBlmbcs 512 -MHlmbcs 512 -MMmcs 30 -P 1048576 -t 5000000 -stbt db>
         ├─1581884 erl_child_setup 65536
         ├─1581943 inet_gethost 4
         └─1581944 inet_gethost 4

启动、停止、重启rabbitmq

sudo service rabbitmq-server start    # 启动
sudo service rabbitmq-server stop     # 停止
sudo service rabbitmq-server restart  # 重启 

执行了上面的步骤,rabbitMq已经安装成功。

启用 web端可视化操作界面,我们还需要配置Management Plugin插件

sudo rabbitmq-plugins enable rabbitmq_management   # 启用插件
sudo service rabbitmq-server restart    # 重启

此时,应该可以通过 http://localhost:15672/ 查看,使用默认账户guest/guest 登录。