簡體   English   中英

安全地從struct sockaddr轉換為struct sockaddr_storage

[英]Safely converting from struct sockaddr to struct sockaddr_storage

我有一個函數,它接受“struct sockaddr *”作為參數(讓我們調用這個input_address),然后我需要操作該地址,可能是sockaddr_in或sockaddr_in6,因為我同時支持IPv4和IPv6。

我得到了一些內存損壞並試圖跟蹤它的源代碼,並且在此過程中發現了一些似乎可疑的代碼,所以我想驗證這是否是正確的做事方式。

struct sockaddr_storage *input_address_storage = (struct sockaddr_storage *) input_address;
struct sockaddr_storage result = [UtilityClass performSomeOperation: *input_address_storage];

起初我認為第一行中的強制轉換是安全的,但是在第二行中我需要取消引用該指針,這看起來可能是錯誤的。 我擔心的原因是它最終可能會復制超出原始結構的內存(因為sockaddr_in比sockaddr_in6短)。 我不確定這是否會導致內存損壞(我的猜測是否定的),但是這段代碼給了我一種不好的感覺。

我無法改變我的函數采用“struct sockaddr *”的事實,所以似乎很難解決這種類型的代碼,但我想避免從我不應該的內存位置進行復制。

如果有人能夠驗證我所做的事情是否錯誤,以及解決這個問題的最佳方法,我會很感激。

編輯:由於某種原因,管理員已經為C#更改了我的C標簽。 我給出的代碼主要是C,來自目標C的一個函數調用並不重要。 那個電話可能是C.

您的方法的問題是您正在將現有的struct sockaddr*轉換為struct sockaddr_storage* 想象一下如果原版是一個``struct sockaddr_in會發生什么. Since . Since sizeof(struct sockaddr_in)<sizeof(struct sockaddr_storage)`,內存清理程序會抱怨未綁定的內存引用。

struct sockaddr_storage本質上是一個包含 struct sockaddr_instruct sockaddr_in6容器

因此,當您想要傳入struct sockaddr*對象但希望為sockaddr_insockaddr_in6分配足夠的內存時,它很有用。

一個很好的例子是recvfrom(3)調用:

ssize_t recvfrom(int socket, void *restrict buffer, size_t length,
                 int flags, struct sockaddr *restrict address,
                 socklen_t *restrict address_len);

由於address需要struct sockaddr*對象,我們首先構造一個struct sockaddr_storage ,並將其傳遞給:

struct sockaddr_storage address;
socklen_t address_length = sizeof(struct sockaddr_storage);
ssize_t ret = recvfrom(fd, buffer, buffer_length, 0, (struct sockaddr*)&address, &address_length);

if (address.ss_family == AF_INET) {
  DoIpv4Work((struct sockaddr_in*)&address, ...);
} else if (address.ss_family == AF_INET6) {
  DoIpv6Work((struct sockaddr_in6*)&address, ...);
}

您和我的方法的不同之處在於我分配了一個struct sockaddr_storage然后將其用作struct sockaddr ,但是您執行REVERSE ,並使用struct sockaddr然后將其用作struct sockaddr_storage

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM