2025年3月13日木曜日

關於oversip的編譯問題的處理流程 (本身使用ruby 2.2以後版本會編譯錯誤,內附third party的stud無法支援openssl 1.1以後版本)

前置作業:因為oversip必須從原始碼開始編譯,先安裝相關套件。一個個試誤列出來。

sudo yum install ruby

sudo yum install ruby-devel

sudo yum install cmake

sudo yum install gcc

sudo yum install g++

 

gem install oversip

出現錯誤

iobuffer.c:8:10: fatal error: rubyio.h: No such file or directory

    8 | #include "rubyio.h"

      |          ^~~~~~~~~~

compilation terminated.

原因:ruby 2.2版之後把rubyio.h 更改結構為 ruby/io.h 

解決方案:在/usr/include/ruby/backwards 新增rubyio.h檔案,內容如下:

#include "ruby/io.h"


繼續安裝gem install oversip

出現錯誤

em.cpp: In member function ‘bool EventMachine_t::_RunEpollOnce()’:

em.h:25:20: error: ‘rb_thread_select’ was not declared in this scope; did you mean ‘rb_thread_sleep’?

   25 |   #define EmSelect rb_thread_select

      |                    ^~~~~~~~~~~~~~~~


原因:oversip的依賴套件:eventmachine-le 指定版本不支援ruby 2.2以上版本。

解決方案:查詢github上面的oversip已解決此問題(改用eventmachine 1.2),改從github取得oversip最新版本。

git clone https://github.com/versatica/OverSIP.git

cd ~/OverSIP

gem build oversip  (產生oversip-2.0.4.gem)

gem install oversip-2.0.4.gem

 

出現錯誤

Could not create Makefile due to some reason, probably lack of necessary

libraries and/or headers.  Check the mkmf.log file for more details.  You may

need configuration options.

stud.c:60:10: fatal error: ev.h: No such file or directory

   60 | #include <ev.h>

      |          ^~~~~~

compilation terminated.

 

 

使用find尋找mkmf.log:  find . -name 'mkmf.log'

mkmf.log 位置: .rvm/gems/ruby-2.7.2/gems/oversip-2.0.4/thirdparty/stud/mkmf.log (此為使用rvm之後的環境,供參考)


原因:ev.h的路徑錯誤。使用連結解決:

sudo ln -s /usr/include/libev/ev.h /usr/include/ev.h


還是出錯,原因相同。查詢發現ev.h不存在。

安裝libev-devel:  sudo yum install libev-devel



出現錯誤

In file included from /usr/include/openssl/x509.h:36,

                 from stud.c:56:

/usr/include/openssl/rsa.h:301:28: note: declared here

  301 | OSSL_DEPRECATEDIN_3_0 void RSA_free(RSA *r);

      |                            ^~~~~~~~

stud.c: In function ‘end_handshake’:

stud.c:921:16: error: invalid use of incomplete typedef ‘SSL’ {aka ‘struct ssl_st’}

  921 |     if (ps->ssl->s3) {

      |                ^~

stud.c:922:16: error: invalid use of incomplete typedef ‘SSL’ {aka ‘struct ssl_st’}

  922 |         ps->ssl->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS;

      |                ^~

make: *** [<builtin>: stud.o] Error 1


以下都是stud.c的編譯問題。解決方案:取得stud的最新版,並修正openssl相關的編譯錯誤。

cd OverSIP/thirdparty/stud

git clone https://github.com/bumptech/stud.git

tar cvzf stud.tar.gz stud/*

cd ~/OverSIP

gem build oversip  (產生oversip-2.0.4.gem)

gem install oversip-2.0.4.gem

 

仍然出一樣的錯誤。

修改 OverSIP/thirdparty/stud/stud/stud.c  #1063

ps->ssl->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS;   

-> 

SSL_set_options(ps->ssl, SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS);


繼續安裝,出錯:

stud.c:551:14: error: invalid use of incomplete typedef ‘SSL_CTX’ {aka ‘struct ssl_ctx_s’}

  551 |           ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);

      |              ^~

stud.c:551:44: error: invalid use of incomplete typedef ‘SSL_CTX’ {aka ‘struct ssl_ctx_s

查看stud.c, #551該行全文:

rsa = PEM_read_bio_RSAPrivateKey(bio, NULL,

          ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);

 

查資料發現openssl的新版不給直接存取SSL Context,必須使用存取函數處理。修改stud.c #551 

rsa = PEM_read_bio_RSAPrivateKey(bio, NULL,

          ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);

-> 

rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, SSL_CTX_get_default_passwd_cb

(ctx), SSL_CTX_get_default_passwd_cb_userdata(ctx));


避免重複處理,直接在OverSIP/thirdparty/stud/stud 執行make, 出錯。

stud.c:752:28: error: invalid use of incomplete typedef ‘X509_NAME_ENTRY’ {aka ‘struct X509_name_entry_st’}

  752 |         PUSH_CTX(x509_entry->value, ctx);

修改 stud.c #752

PUSH_CTX(x509_entry->value, ctx);  

->  

PUSH_CTX(X509_NAME_ENTRY_get_data(x509_entry), ctx);

make終於成功。正式進行gem的opersip安裝
cd ~/OverSIP
gem build oversip
gem install oversip-2.0.4.gem

安裝成功。